namespace ParserGenerator.Languages.LocalTypeInference
{
    public partial interface ISyntaxTreeNode : global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>
    {
        global::ParserGenerator.Input.SourceContext Context { get; set; }
    }

    [global::System.Serializable]
    public sealed partial class Identifier : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public string Name { get; }
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        private Identifier(string name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            Name = name;
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Identifier New(string name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.Identifier(name, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.Identifier Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.Identifier(Name, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.Identifier WithName(string name)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.Identifier(name, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.Identifier WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.Identifier(Name, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteIdentifier(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class IntLiteral : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public System.Numerics.BigInteger Value { get; }
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        private IntLiteral(System.Numerics.BigInteger value, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            Value = value;
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.IntLiteral New(System.Numerics.BigInteger value, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            return new global::ParserGenerator.Languages.LocalTypeInference.IntLiteral(value, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.IntLiteral Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.IntLiteral(Value, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.IntLiteral WithValue(System.Numerics.BigInteger value)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            return new global::ParserGenerator.Languages.LocalTypeInference.IntLiteral(value, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.IntLiteral WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.IntLiteral(Value, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteIntLiteral(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class Parameter : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.Identifier Name { get; }
        public global::ParserGenerator.Languages.LocalTypeInference.Type Type { get; }
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 2;

        private Parameter(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Languages.LocalTypeInference.Type type, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            if (type == null)
                throw new global::System.ArgumentNullException(nameof(type));
            Name = name;
            Type = type;
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Parameter New(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Languages.LocalTypeInference.Type type, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            if (type == null)
                throw new global::System.ArgumentNullException(nameof(type));
            return new global::ParserGenerator.Languages.LocalTypeInference.Parameter(name, type, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.Parameter Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.Parameter(Name, Type, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.Parameter WithName(global::ParserGenerator.Languages.LocalTypeInference.Identifier name)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.Parameter(name, Type, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.Parameter WithType(global::ParserGenerator.Languages.LocalTypeInference.Type type)
        {
            if (type == null)
                throw new global::System.ArgumentNullException(nameof(type));
            return new global::ParserGenerator.Languages.LocalTypeInference.Parameter(Name, type, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.Parameter WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.Parameter(Name, Type, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Name;
                    case 1:
                        return Type;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Name;
            yield return Type;
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteParameter(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class ParameterList : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Collections.Sequence<Parameter> Items { get; }
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => Items.Count;

        private ParameterList(global::ParserGenerator.Collections.Sequence<Parameter> items, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            Items = items;
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.ParameterList New(global::ParserGenerator.Collections.Sequence<Parameter> items, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            return new global::ParserGenerator.Languages.LocalTypeInference.ParameterList(items, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ParameterList Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ParameterList(Items, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ParameterList WithItems(global::ParserGenerator.Collections.Sequence<Parameter> items)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            return new global::ParserGenerator.Languages.LocalTypeInference.ParameterList(items, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ParameterList WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ParameterList(Items, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                if (i < 0)
                    throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                int count = 0;
                if (count <= i && i < count + Items.Count)
                    return Items[i - count];
                count += Items.Count;
                throw new global::System.ArgumentOutOfRangeException(nameof(i));
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            return Items.GetEnumerator();
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteParameterList(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class ArgumentList : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Collections.Sequence<Expression> Items { get; }
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => Items.Count;

        private ArgumentList(global::ParserGenerator.Collections.Sequence<Expression> items, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            Items = items;
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.ArgumentList New(global::ParserGenerator.Collections.Sequence<Expression> items, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            return new global::ParserGenerator.Languages.LocalTypeInference.ArgumentList(items, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ArgumentList Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ArgumentList(Items, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ArgumentList WithItems(global::ParserGenerator.Collections.Sequence<Expression> items)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            return new global::ParserGenerator.Languages.LocalTypeInference.ArgumentList(items, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ArgumentList WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ArgumentList(Items, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                if (i < 0)
                    throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                int count = 0;
                if (count <= i && i < count + Items.Count)
                    return Items[i - count];
                count += Items.Count;
                throw new global::System.ArgumentOutOfRangeException(nameof(i));
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            return Items.GetEnumerator();
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteArgumentList(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class TypeParameter : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.Identifier Name { get; }
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 1;

        private TypeParameter(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            Name = name;
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.TypeParameter New(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeParameter(name, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeParameter Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeParameter(Name, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeParameter WithName(global::ParserGenerator.Languages.LocalTypeInference.Identifier name)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeParameter(name, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeParameter WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeParameter(Name, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Name;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Name;
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteTypeParameter(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class TypeParameterList : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Collections.Sequence<TypeParameter> Items { get; }
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => Items.Count;

        private TypeParameterList(global::ParserGenerator.Collections.Sequence<TypeParameter> items, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            Items = items;
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList New(global::ParserGenerator.Collections.Sequence<TypeParameter> items, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList(items, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList(Items, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList WithItems(global::ParserGenerator.Collections.Sequence<TypeParameter> items)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList(items, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList(Items, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                if (i < 0)
                    throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                int count = 0;
                if (count <= i && i < count + Items.Count)
                    return Items[i - count];
                count += Items.Count;
                throw new global::System.ArgumentOutOfRangeException(nameof(i));
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            return Items.GetEnumerator();
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteTypeParameterList(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class TypeArgumentList : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Collections.Sequence<Type> Items { get; }
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => Items.Count;

        private TypeArgumentList(global::ParserGenerator.Collections.Sequence<Type> items, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            Items = items;
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList New(global::ParserGenerator.Collections.Sequence<Type> items, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList(items, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList(Items, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList WithItems(global::ParserGenerator.Collections.Sequence<Type> items)
        {
            if (items == null)
                throw new global::System.ArgumentNullException(nameof(items));
            if (items.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(items)), nameof(items));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList(items, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList(Items, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                if (i < 0)
                    throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                int count = 0;
                if (count <= i && i < count + Items.Count)
                    return Items[i - count];
                count += Items.Count;
                throw new global::System.ArgumentOutOfRangeException(nameof(i));
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            return Items.GetEnumerator();
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteTypeArgumentList(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public enum ExpressionCategory
    {
        Variable,
        False,
        True,
        IntLiteral,
        Group,
        Unary,
        Binary,
        Function,
        Call,
    }

    [global::System.Serializable]
    public abstract partial class Expression : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        public abstract global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory Tag { get; }
        public bool IsVariable => this is global::ParserGenerator.Languages.LocalTypeInference.VariableExpression;
        public bool IsFalse => this is global::ParserGenerator.Languages.LocalTypeInference.FalseExpression;
        public bool IsTrue => this is global::ParserGenerator.Languages.LocalTypeInference.TrueExpression;
        public bool IsIntLiteral => this is global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression;
        public bool IsGroup => this is global::ParserGenerator.Languages.LocalTypeInference.GroupExpression;
        public bool IsUnary => this is global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression;
        public bool IsBinary => this is global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression;
        public bool IsFunction => this is global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression;
        public bool IsCall => this is global::ParserGenerator.Languages.LocalTypeInference.CallExpression;
        public global::ParserGenerator.Languages.LocalTypeInference.VariableExpression AsVariable => (global::ParserGenerator.Languages.LocalTypeInference.VariableExpression)this;
        public global::ParserGenerator.Languages.LocalTypeInference.FalseExpression AsFalse => (global::ParserGenerator.Languages.LocalTypeInference.FalseExpression)this;
        public global::ParserGenerator.Languages.LocalTypeInference.TrueExpression AsTrue => (global::ParserGenerator.Languages.LocalTypeInference.TrueExpression)this;
        public global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression AsIntLiteral => (global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression)this;
        public global::ParserGenerator.Languages.LocalTypeInference.GroupExpression AsGroup => (global::ParserGenerator.Languages.LocalTypeInference.GroupExpression)this;
        public global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression AsUnary => (global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression)this;
        public global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression AsBinary => (global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression)this;
        public global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression AsFunction => (global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression)this;
        public global::ParserGenerator.Languages.LocalTypeInference.CallExpression AsCall => (global::ParserGenerator.Languages.LocalTypeInference.CallExpression)this;

        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        internal Expression(global::ParserGenerator.Input.SourceContext context = null)
        {
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Expression NewVariable(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.VariableExpression(name, context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Expression NewFalse(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.FalseExpression(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Expression NewTrue(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TrueExpression(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Expression NewIntLiteral(global::ParserGenerator.Languages.LocalTypeInference.IntLiteral value, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            return new global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression(value, context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Expression NewGroup(global::ParserGenerator.Languages.LocalTypeInference.Expression operand, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::ParserGenerator.Languages.LocalTypeInference.GroupExpression(operand, context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Expression NewUnary(global::ParserGenerator.Languages.LocalTypeInference.UnaryOp op, global::ParserGenerator.Languages.LocalTypeInference.Expression operand, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (op == null)
                throw new global::System.ArgumentNullException(nameof(op));
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression(op, operand, context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Expression NewBinary(global::ParserGenerator.Languages.LocalTypeInference.Expression left, global::ParserGenerator.Languages.LocalTypeInference.BinaryOp op, global::ParserGenerator.Languages.LocalTypeInference.Expression right, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            if (op == null)
                throw new global::System.ArgumentNullException(nameof(op));
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            return new global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression(left, op, right, context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Expression NewFunction(TypeParameterList typeParameters, global::ParserGenerator.Languages.LocalTypeInference.ParameterList parameters, global::ParserGenerator.Languages.LocalTypeInference.Expression body, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (parameters == null)
                throw new global::System.ArgumentNullException(nameof(parameters));
            if (body == null)
                throw new global::System.ArgumentNullException(nameof(body));
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression(typeParameters, parameters, body, context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Expression NewCall(global::ParserGenerator.Languages.LocalTypeInference.Expression function, TypeArgumentList typeArguments, global::ParserGenerator.Languages.LocalTypeInference.ArgumentList arguments, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (function == null)
                throw new global::System.ArgumentNullException(nameof(function));
            if (arguments == null)
                throw new global::System.ArgumentNullException(nameof(arguments));
            return new global::ParserGenerator.Languages.LocalTypeInference.CallExpression(function, typeArguments, arguments, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            throw new global::System.NotImplementedException();
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();
        public abstract void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d);
        public abstract void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v);

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteExpression(this, w, d);
                return writer.ToString().Trim();
            }
        }

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            return ToString(v, -1);
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class VariableExpression : global::ParserGenerator.Languages.LocalTypeInference.Expression, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.Identifier Name { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory.Variable;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 1;

        internal VariableExpression(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            Name = name;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.VariableExpression New(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.VariableExpression(name, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.VariableExpression Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.VariableExpression(Name, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.VariableExpression WithName(global::ParserGenerator.Languages.LocalTypeInference.Identifier name)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.VariableExpression(name, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.VariableExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.VariableExpression(Name, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Name;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Name;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteVariableExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkVariableExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class FalseExpression : global::ParserGenerator.Languages.LocalTypeInference.Expression, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory.False;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal FalseExpression(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.FalseExpression New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.FalseExpression(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FalseExpression Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.FalseExpression(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FalseExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.FalseExpression(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteFalseExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkFalseExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class TrueExpression : global::ParserGenerator.Languages.LocalTypeInference.Expression, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory.True;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal TrueExpression(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.TrueExpression New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TrueExpression(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TrueExpression Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TrueExpression(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TrueExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TrueExpression(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteTrueExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkTrueExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class IntLiteralExpression : global::ParserGenerator.Languages.LocalTypeInference.Expression, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.IntLiteral Value { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory.IntLiteral;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 1;

        internal IntLiteralExpression(global::ParserGenerator.Languages.LocalTypeInference.IntLiteral value, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            Value = value;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression New(global::ParserGenerator.Languages.LocalTypeInference.IntLiteral value, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            return new global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression(value, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression(Value, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression WithValue(global::ParserGenerator.Languages.LocalTypeInference.IntLiteral value)
        {
            if (value == null)
                throw new global::System.ArgumentNullException(nameof(value));
            return new global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression(value, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression(Value, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Value;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Value;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteIntLiteralExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkIntLiteralExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class GroupExpression : global::ParserGenerator.Languages.LocalTypeInference.Expression, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.Expression Operand { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory.Group;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 1;

        internal GroupExpression(global::ParserGenerator.Languages.LocalTypeInference.Expression operand, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            Operand = operand;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.GroupExpression New(global::ParserGenerator.Languages.LocalTypeInference.Expression operand, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::ParserGenerator.Languages.LocalTypeInference.GroupExpression(operand, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.GroupExpression Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.GroupExpression(Operand, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.GroupExpression WithOperand(global::ParserGenerator.Languages.LocalTypeInference.Expression operand)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::ParserGenerator.Languages.LocalTypeInference.GroupExpression(operand, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.GroupExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.GroupExpression(Operand, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Operand;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Operand;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteGroupExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkGroupExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class UnaryExpression : global::ParserGenerator.Languages.LocalTypeInference.Expression, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.UnaryOp Op { get; }
        public global::ParserGenerator.Languages.LocalTypeInference.Expression Operand { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory.Unary;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 2;

        internal UnaryExpression(global::ParserGenerator.Languages.LocalTypeInference.UnaryOp op, global::ParserGenerator.Languages.LocalTypeInference.Expression operand, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (op == null)
                throw new global::System.ArgumentNullException(nameof(op));
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            Op = op;
            Operand = operand;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression New(global::ParserGenerator.Languages.LocalTypeInference.UnaryOp op, global::ParserGenerator.Languages.LocalTypeInference.Expression operand, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (op == null)
                throw new global::System.ArgumentNullException(nameof(op));
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression(op, operand, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression(Op, Operand, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression WithOp(global::ParserGenerator.Languages.LocalTypeInference.UnaryOp op)
        {
            if (op == null)
                throw new global::System.ArgumentNullException(nameof(op));
            return new global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression(op, Operand, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression WithOperand(global::ParserGenerator.Languages.LocalTypeInference.Expression operand)
        {
            if (operand == null)
                throw new global::System.ArgumentNullException(nameof(operand));
            return new global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression(Op, operand, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression(Op, Operand, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Op;
                    case 1:
                        return Operand;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Op;
            yield return Operand;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteUnaryExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkUnaryExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class BinaryExpression : global::ParserGenerator.Languages.LocalTypeInference.Expression, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.Expression Left { get; }
        public global::ParserGenerator.Languages.LocalTypeInference.BinaryOp Op { get; }
        public global::ParserGenerator.Languages.LocalTypeInference.Expression Right { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory.Binary;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 3;

        internal BinaryExpression(global::ParserGenerator.Languages.LocalTypeInference.Expression left, global::ParserGenerator.Languages.LocalTypeInference.BinaryOp op, global::ParserGenerator.Languages.LocalTypeInference.Expression right, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            if (op == null)
                throw new global::System.ArgumentNullException(nameof(op));
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            Left = left;
            Op = op;
            Right = right;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression New(global::ParserGenerator.Languages.LocalTypeInference.Expression left, global::ParserGenerator.Languages.LocalTypeInference.BinaryOp op, global::ParserGenerator.Languages.LocalTypeInference.Expression right, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            if (op == null)
                throw new global::System.ArgumentNullException(nameof(op));
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            return new global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression(left, op, right, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression(Left, Op, Right, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression WithLeft(global::ParserGenerator.Languages.LocalTypeInference.Expression left)
        {
            if (left == null)
                throw new global::System.ArgumentNullException(nameof(left));
            return new global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression(left, Op, Right, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression WithOp(global::ParserGenerator.Languages.LocalTypeInference.BinaryOp op)
        {
            if (op == null)
                throw new global::System.ArgumentNullException(nameof(op));
            return new global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression(Left, op, Right, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression WithRight(global::ParserGenerator.Languages.LocalTypeInference.Expression right)
        {
            if (right == null)
                throw new global::System.ArgumentNullException(nameof(right));
            return new global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression(Left, Op, right, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression(Left, Op, Right, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Left;
                    case 1:
                        return Op;
                    case 2:
                        return Right;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Left;
            yield return Op;
            yield return Right;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteBinaryExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkBinaryExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class FunctionExpression : global::ParserGenerator.Languages.LocalTypeInference.Expression, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public TypeParameterList TypeParameters { get; }
        public global::ParserGenerator.Languages.LocalTypeInference.ParameterList Parameters { get; }
        public global::ParserGenerator.Languages.LocalTypeInference.Expression Body { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory.Function;

        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count
        {
            get
            {
                int count = 0;
                count += ((TypeParameters != null) ? (1) : (0));
                count++;
                count++;
                return count;
            }
        }

        internal FunctionExpression(TypeParameterList typeParameters, global::ParserGenerator.Languages.LocalTypeInference.ParameterList parameters, global::ParserGenerator.Languages.LocalTypeInference.Expression body, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (parameters == null)
                throw new global::System.ArgumentNullException(nameof(parameters));
            if (body == null)
                throw new global::System.ArgumentNullException(nameof(body));
            TypeParameters = typeParameters;
            Parameters = parameters;
            Body = body;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression New(TypeParameterList typeParameters, global::ParserGenerator.Languages.LocalTypeInference.ParameterList parameters, global::ParserGenerator.Languages.LocalTypeInference.Expression body, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (parameters == null)
                throw new global::System.ArgumentNullException(nameof(parameters));
            if (body == null)
                throw new global::System.ArgumentNullException(nameof(body));
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression(typeParameters, parameters, body, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression(TypeParameters, Parameters, Body, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression WithTypeParameters(TypeParameterList typeParameters)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression(typeParameters, Parameters, Body, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression WithParameters(global::ParserGenerator.Languages.LocalTypeInference.ParameterList parameters)
        {
            if (parameters == null)
                throw new global::System.ArgumentNullException(nameof(parameters));
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression(TypeParameters, parameters, Body, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression WithBody(global::ParserGenerator.Languages.LocalTypeInference.Expression body)
        {
            if (body == null)
                throw new global::System.ArgumentNullException(nameof(body));
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression(TypeParameters, Parameters, body, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression(TypeParameters, Parameters, Body, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                if (i < 0)
                    throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                int count = 0;
                if (TypeParameters != null)
                {
                    if (i == count)
                        return TypeParameters;
                    count++;
                }
                if (i == count)
                    return Parameters;
                count++;
                if (i == count)
                    return Body;
                count++;
                throw new global::System.ArgumentOutOfRangeException(nameof(i));
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            if (TypeParameters != null)
                yield return TypeParameters;
            yield return Parameters;
            yield return Body;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteFunctionExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkFunctionExpression(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class CallExpression : global::ParserGenerator.Languages.LocalTypeInference.Expression, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.Expression Function { get; }
        public TypeArgumentList TypeArguments { get; }
        public global::ParserGenerator.Languages.LocalTypeInference.ArgumentList Arguments { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.ExpressionCategory.Call;

        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count
        {
            get
            {
                int count = 0;
                count++;
                count += ((TypeArguments != null) ? (1) : (0));
                count++;
                return count;
            }
        }

        internal CallExpression(global::ParserGenerator.Languages.LocalTypeInference.Expression function, TypeArgumentList typeArguments, global::ParserGenerator.Languages.LocalTypeInference.ArgumentList arguments, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (function == null)
                throw new global::System.ArgumentNullException(nameof(function));
            if (arguments == null)
                throw new global::System.ArgumentNullException(nameof(arguments));
            Function = function;
            TypeArguments = typeArguments;
            Arguments = arguments;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.CallExpression New(global::ParserGenerator.Languages.LocalTypeInference.Expression function, TypeArgumentList typeArguments, global::ParserGenerator.Languages.LocalTypeInference.ArgumentList arguments, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (function == null)
                throw new global::System.ArgumentNullException(nameof(function));
            if (arguments == null)
                throw new global::System.ArgumentNullException(nameof(arguments));
            return new global::ParserGenerator.Languages.LocalTypeInference.CallExpression(function, typeArguments, arguments, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.CallExpression Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.CallExpression(Function, TypeArguments, Arguments, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.CallExpression WithFunction(global::ParserGenerator.Languages.LocalTypeInference.Expression function)
        {
            if (function == null)
                throw new global::System.ArgumentNullException(nameof(function));
            return new global::ParserGenerator.Languages.LocalTypeInference.CallExpression(function, TypeArguments, Arguments, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.CallExpression WithTypeArguments(TypeArgumentList typeArguments)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.CallExpression(Function, typeArguments, Arguments, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.CallExpression WithArguments(global::ParserGenerator.Languages.LocalTypeInference.ArgumentList arguments)
        {
            if (arguments == null)
                throw new global::System.ArgumentNullException(nameof(arguments));
            return new global::ParserGenerator.Languages.LocalTypeInference.CallExpression(Function, TypeArguments, arguments, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.CallExpression WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.CallExpression(Function, TypeArguments, Arguments, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                if (i < 0)
                    throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                int count = 0;
                if (i == count)
                    return Function;
                count++;
                if (TypeArguments != null)
                {
                    if (i == count)
                        return TypeArguments;
                    count++;
                }
                if (i == count)
                    return Arguments;
                count++;
                throw new global::System.ArgumentOutOfRangeException(nameof(i));
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Function;
            if (TypeArguments != null)
                yield return TypeArguments;
            yield return Arguments;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteCallExpression(this, writer, d);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkCallExpression(this);
        }
    }

    [global::System.Serializable]
    public enum UnaryOpCategory
    {
        Positive,
        Negative,
        LogicalNot,
    }

    [global::System.Serializable]
    public abstract partial class UnaryOp : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        public abstract global::ParserGenerator.Languages.LocalTypeInference.UnaryOpCategory Tag { get; }
        public bool IsPositive => this is global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp;
        public bool IsNegative => this is global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp;
        public bool IsLogicalNot => this is global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp;
        public global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp AsPositive => (global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp AsNegative => (global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp AsLogicalNot => (global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp)this;

        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        internal UnaryOp(global::ParserGenerator.Input.SourceContext context = null)
        {
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.UnaryOp NewPositive(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.UnaryOp NewNegative(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.UnaryOp NewLogicalNot(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            throw new global::System.NotImplementedException();
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();
        public abstract void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer);
        public abstract void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v);

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteUnaryOp(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class PositiveUnaryOp : global::ParserGenerator.Languages.LocalTypeInference.UnaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.UnaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.UnaryOpCategory.Positive;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal PositiveUnaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WritePositiveUnaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkPositiveUnaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class NegativeUnaryOp : global::ParserGenerator.Languages.LocalTypeInference.UnaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.UnaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.UnaryOpCategory.Negative;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal NegativeUnaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteNegativeUnaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkNegativeUnaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class LogicalNotUnaryOp : global::ParserGenerator.Languages.LocalTypeInference.UnaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.UnaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.UnaryOpCategory.LogicalNot;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal LogicalNotUnaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteLogicalNotUnaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkLogicalNotUnaryOp(this);
        }
    }

    [global::System.Serializable]
    public enum BinaryOpCategory
    {
        Add,
        Subtract,
        Multiply,
        Divide,
        Modulo,
        EqualTo,
        NotEqualTo,
        LessThan,
        LessEqual,
        GreaterThan,
        GreaterEqual,
        LogicalAnd,
        LogicalOr,
    }

    [global::System.Serializable]
    public abstract partial class BinaryOp : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        public abstract global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag { get; }
        public bool IsAdd => this is global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp;
        public bool IsSubtract => this is global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp;
        public bool IsMultiply => this is global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp;
        public bool IsDivide => this is global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp;
        public bool IsModulo => this is global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp;
        public bool IsEqualTo => this is global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp;
        public bool IsNotEqualTo => this is global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp;
        public bool IsLessThan => this is global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp;
        public bool IsLessEqual => this is global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp;
        public bool IsGreaterThan => this is global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp;
        public bool IsGreaterEqual => this is global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp;
        public bool IsLogicalAnd => this is global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp;
        public bool IsLogicalOr => this is global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp;
        public global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp AsAdd => (global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp AsSubtract => (global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp AsMultiply => (global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp AsDivide => (global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp AsModulo => (global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp AsEqualTo => (global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp AsNotEqualTo => (global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp AsLessThan => (global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp AsLessEqual => (global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp AsGreaterThan => (global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp AsGreaterEqual => (global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp AsLogicalAnd => (global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp)this;
        public global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp AsLogicalOr => (global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp)this;

        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        internal BinaryOp(global::ParserGenerator.Input.SourceContext context = null)
        {
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewAdd(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewSubtract(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewMultiply(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewDivide(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewModulo(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewEqualTo(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewNotEqualTo(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewLessThan(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewLessEqual(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewGreaterThan(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewGreaterEqual(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewLogicalAnd(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BinaryOp NewLogicalOr(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            throw new global::System.NotImplementedException();
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();
        public abstract void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer);
        public abstract void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v);

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteBinaryOp(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class AddBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.Add;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal AddBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteAddBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkAddBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class SubtractBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.Subtract;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal SubtractBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteSubtractBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkSubtractBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class MultiplyBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.Multiply;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal MultiplyBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteMultiplyBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkMultiplyBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class DivideBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.Divide;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal DivideBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteDivideBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkDivideBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class ModuloBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.Modulo;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal ModuloBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteModuloBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkModuloBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class EqualToBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.EqualTo;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal EqualToBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteEqualToBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkEqualToBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class NotEqualToBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.NotEqualTo;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal NotEqualToBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteNotEqualToBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkNotEqualToBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class LessThanBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.LessThan;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal LessThanBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteLessThanBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkLessThanBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class LessEqualBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.LessEqual;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal LessEqualBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteLessEqualBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkLessEqualBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class GreaterThanBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.GreaterThan;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal GreaterThanBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteGreaterThanBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkGreaterThanBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class GreaterEqualBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.GreaterEqual;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal GreaterEqualBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteGreaterEqualBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkGreaterEqualBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class LogicalAndBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.LogicalAnd;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal LogicalAndBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteLogicalAndBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkLogicalAndBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class LogicalOrBinaryOp : global::ParserGenerator.Languages.LocalTypeInference.BinaryOp, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.BinaryOpCategory.LogicalOr;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal LogicalOrBinaryOp(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteLogicalOrBinaryOp(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkLogicalOrBinaryOp(this);
        }
    }

    [global::System.Serializable]
    public enum TypeCategory
    {
        Variable,
        Object,
        Null,
        Bool,
        Int,
        Function,
    }

    [global::System.Serializable]
    public abstract partial class Type : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        public abstract global::ParserGenerator.Languages.LocalTypeInference.TypeCategory Tag { get; }
        public bool IsVariable => this is global::ParserGenerator.Languages.LocalTypeInference.VariableType;
        public bool IsObject => this is global::ParserGenerator.Languages.LocalTypeInference.ObjectType;
        public bool IsNull => this is global::ParserGenerator.Languages.LocalTypeInference.NullType;
        public bool IsBool => this is global::ParserGenerator.Languages.LocalTypeInference.BoolType;
        public bool IsInt => this is global::ParserGenerator.Languages.LocalTypeInference.IntType;
        public bool IsFunction => this is global::ParserGenerator.Languages.LocalTypeInference.FunctionType;
        public global::ParserGenerator.Languages.LocalTypeInference.VariableType AsVariable => (global::ParserGenerator.Languages.LocalTypeInference.VariableType)this;
        public global::ParserGenerator.Languages.LocalTypeInference.ObjectType AsObject => (global::ParserGenerator.Languages.LocalTypeInference.ObjectType)this;
        public global::ParserGenerator.Languages.LocalTypeInference.NullType AsNull => (global::ParserGenerator.Languages.LocalTypeInference.NullType)this;
        public global::ParserGenerator.Languages.LocalTypeInference.BoolType AsBool => (global::ParserGenerator.Languages.LocalTypeInference.BoolType)this;
        public global::ParserGenerator.Languages.LocalTypeInference.IntType AsInt => (global::ParserGenerator.Languages.LocalTypeInference.IntType)this;
        public global::ParserGenerator.Languages.LocalTypeInference.FunctionType AsFunction => (global::ParserGenerator.Languages.LocalTypeInference.FunctionType)this;

        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        internal Type(global::ParserGenerator.Input.SourceContext context = null)
        {
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Type NewVariable(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.VariableType(name, context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Type NewObject(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ObjectType(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Type NewNull(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NullType(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Type NewBool(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.BoolType(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Type NewInt(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.IntType(context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.Type NewFunction(TypeParameterList typeParameters, global::ParserGenerator.Collections.Sequence<Type> sources, global::ParserGenerator.Languages.LocalTypeInference.Type target, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (sources == null)
                throw new global::System.ArgumentNullException(nameof(sources));
            if (sources.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(sources)), nameof(sources));
            if (target == null)
                throw new global::System.ArgumentNullException(nameof(target));
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionType(typeParameters, sources, target, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            throw new global::System.NotImplementedException();
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();
        public abstract void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer);
        public abstract void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v);

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteType(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class VariableType : global::ParserGenerator.Languages.LocalTypeInference.Type, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.Identifier Name { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.TypeCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.TypeCategory.Variable;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 1;

        internal VariableType(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            Name = name;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.VariableType New(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.VariableType(name, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.VariableType Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.VariableType(Name, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.VariableType WithName(global::ParserGenerator.Languages.LocalTypeInference.Identifier name)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.VariableType(name, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.VariableType WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.VariableType(Name, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Name;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Name;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteVariableType(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkVariableType(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class ObjectType : global::ParserGenerator.Languages.LocalTypeInference.Type, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.TypeCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.TypeCategory.Object;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal ObjectType(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.ObjectType New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ObjectType(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ObjectType Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ObjectType(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ObjectType WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ObjectType(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteObjectType(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkObjectType(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class NullType : global::ParserGenerator.Languages.LocalTypeInference.Type, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.TypeCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.TypeCategory.Null;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal NullType(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.NullType New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NullType(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.NullType Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NullType(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.NullType WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.NullType(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteNullType(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkNullType(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class BoolType : global::ParserGenerator.Languages.LocalTypeInference.Type, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.TypeCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.TypeCategory.Bool;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal BoolType(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.BoolType New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.BoolType(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.BoolType Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.BoolType(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.BoolType WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.BoolType(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteBoolType(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkBoolType(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class IntType : global::ParserGenerator.Languages.LocalTypeInference.Type, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.TypeCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.TypeCategory.Int;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 0;

        internal IntType(global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.IntType New(global::ParserGenerator.Input.SourceContext context = null)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.IntType(context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.IntType Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.IntType(Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.IntType WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.IntType(context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield break;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteIntType(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkIntType(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class FunctionType : global::ParserGenerator.Languages.LocalTypeInference.Type, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public TypeParameterList TypeParameters { get; }
        public global::ParserGenerator.Collections.Sequence<Type> Sources { get; }
        public global::ParserGenerator.Languages.LocalTypeInference.Type Target { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.TypeCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.TypeCategory.Function;

        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count
        {
            get
            {
                int count = 0;
                count += ((TypeParameters != null) ? (1) : (0));
                count += Sources.Count;
                count++;
                return count;
            }
        }

        internal FunctionType(TypeParameterList typeParameters, global::ParserGenerator.Collections.Sequence<Type> sources, global::ParserGenerator.Languages.LocalTypeInference.Type target, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (sources == null)
                throw new global::System.ArgumentNullException(nameof(sources));
            if (sources.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(sources)), nameof(sources));
            if (target == null)
                throw new global::System.ArgumentNullException(nameof(target));
            TypeParameters = typeParameters;
            Sources = sources;
            Target = target;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.FunctionType New(TypeParameterList typeParameters, global::ParserGenerator.Collections.Sequence<Type> sources, global::ParserGenerator.Languages.LocalTypeInference.Type target, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (sources == null)
                throw new global::System.ArgumentNullException(nameof(sources));
            if (sources.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(sources)), nameof(sources));
            if (target == null)
                throw new global::System.ArgumentNullException(nameof(target));
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionType(typeParameters, sources, target, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FunctionType Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionType(TypeParameters, Sources, Target, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FunctionType WithTypeParameters(TypeParameterList typeParameters)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionType(typeParameters, Sources, Target, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FunctionType WithSources(global::ParserGenerator.Collections.Sequence<Type> sources)
        {
            if (sources == null)
                throw new global::System.ArgumentNullException(nameof(sources));
            if (sources.Count <= 0)
                throw new global::System.ArgumentException(string.Format(global::ParserGenerator.SR.ArgumentMustNotBeEmptySequence, nameof(sources)), nameof(sources));
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionType(TypeParameters, sources, Target, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FunctionType WithTarget(global::ParserGenerator.Languages.LocalTypeInference.Type target)
        {
            if (target == null)
                throw new global::System.ArgumentNullException(nameof(target));
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionType(TypeParameters, Sources, target, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.FunctionType WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.FunctionType(TypeParameters, Sources, Target, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                if (i < 0)
                    throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                int count = 0;
                if (TypeParameters != null)
                {
                    if (i == count)
                        return TypeParameters;
                    count++;
                }
                if (count <= i && i < count + Sources.Count)
                    return Sources[i - count];
                count += Sources.Count;
                if (i == count)
                    return Target;
                count++;
                throw new global::System.ArgumentOutOfRangeException(nameof(i));
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            if (TypeParameters != null)
                yield return TypeParameters;
            foreach (var _t1503503 in Sources)
                yield return _t1503503;
            yield return Target;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteFunctionType(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkFunctionType(this);
        }
    }

    [global::System.Serializable]
    public enum VariableBindingCategory
    {
        Value,
        Type,
        TypeSubstitution,
    }

    [global::System.Serializable]
    public abstract partial class VariableBinding : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Input.SourceContext Context { get; set; }
        public abstract global::ParserGenerator.Languages.LocalTypeInference.VariableBindingCategory Tag { get; }
        public bool IsValue => this is global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding;
        public bool IsType => this is global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding;
        public bool IsTypeSubstitution => this is global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding;
        public global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding AsValue => (global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding)this;
        public global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding AsType => (global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding)this;
        public global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding AsTypeSubstitution => (global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding)this;

        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        internal VariableBinding(global::ParserGenerator.Input.SourceContext context = null)
        {
            Context = context;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.VariableBinding NewValue(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Languages.LocalTypeInference.Type type, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            if (type == null)
                throw new global::System.ArgumentNullException(nameof(type));
            return new global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding(name, type, context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.VariableBinding NewType(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding(name, context);
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.VariableBinding NewTypeSubstitution(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Languages.LocalTypeInference.Type type, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            if (type == null)
                throw new global::System.ArgumentNullException(nameof(type));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding(name, type, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                throw new global::System.NotImplementedException();
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            throw new global::System.NotImplementedException();
        }

        global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => ((global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode)this).GetEnumerator();
        public abstract void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer);
        public abstract void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v);

        public string ToString(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            using (var writer = new global::System.IO.StringWriter())
            {
                global::ParserGenerator.Output.IndentedWriter w = new global::ParserGenerator.Output.IndentedWriter(writer);
                v.WriteVariableBinding(this, w);
                return writer.ToString().Trim();
            }
        }

        public sealed override string ToString()
        {
            return ToString(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter.Instance);
        }
    }

    [global::System.Serializable]
    public sealed partial class ValueVariableBinding : global::ParserGenerator.Languages.LocalTypeInference.VariableBinding, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.Identifier Name { get; }
        public global::ParserGenerator.Languages.LocalTypeInference.Type Type { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.VariableBindingCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.VariableBindingCategory.Value;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 2;

        internal ValueVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Languages.LocalTypeInference.Type type, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            if (type == null)
                throw new global::System.ArgumentNullException(nameof(type));
            Name = name;
            Type = type;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding New(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Languages.LocalTypeInference.Type type, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            if (type == null)
                throw new global::System.ArgumentNullException(nameof(type));
            return new global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding(name, type, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding(Name, Type, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding WithName(global::ParserGenerator.Languages.LocalTypeInference.Identifier name)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding(name, Type, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding WithType(global::ParserGenerator.Languages.LocalTypeInference.Type type)
        {
            if (type == null)
                throw new global::System.ArgumentNullException(nameof(type));
            return new global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding(Name, type, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding(Name, Type, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Name;
                    case 1:
                        return Type;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Name;
            yield return Type;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteValueVariableBinding(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkValueVariableBinding(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class TypeVariableBinding : global::ParserGenerator.Languages.LocalTypeInference.VariableBinding, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.Identifier Name { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.VariableBindingCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.VariableBindingCategory.Type;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 1;

        internal TypeVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            Name = name;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding New(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding(name, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding(Name, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding WithName(global::ParserGenerator.Languages.LocalTypeInference.Identifier name)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding(name, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding(Name, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Name;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Name;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteTypeVariableBinding(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkTypeVariableBinding(this);
        }
    }

    [global::System.Serializable]
    public sealed partial class TypeSubstitutionVariableBinding : global::ParserGenerator.Languages.LocalTypeInference.VariableBinding, global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode
    {
        public global::ParserGenerator.Languages.LocalTypeInference.Identifier Name { get; }
        public global::ParserGenerator.Languages.LocalTypeInference.Type Type { get; }
        public sealed override global::ParserGenerator.Languages.LocalTypeInference.VariableBindingCategory Tag => global::ParserGenerator.Languages.LocalTypeInference.VariableBindingCategory.TypeSubstitution;
        int global::System.Collections.Generic.IReadOnlyCollection<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.Count => 2;

        internal TypeSubstitutionVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Languages.LocalTypeInference.Type type, global::ParserGenerator.Input.SourceContext context = null)
            : base(context)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            if (type == null)
                throw new global::System.ArgumentNullException(nameof(type));
            Name = name;
            Type = type;
        }

        public static global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding New(global::ParserGenerator.Languages.LocalTypeInference.Identifier name, global::ParserGenerator.Languages.LocalTypeInference.Type type, global::ParserGenerator.Input.SourceContext context = null)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            if (type == null)
                throw new global::System.ArgumentNullException(nameof(type));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding(name, type, context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding Copy()
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding(Name, Type, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding WithName(global::ParserGenerator.Languages.LocalTypeInference.Identifier name)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding(name, Type, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding WithType(global::ParserGenerator.Languages.LocalTypeInference.Type type)
        {
            if (type == null)
                throw new global::System.ArgumentNullException(nameof(type));
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding(Name, type, Context);
        }

        public global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding WithContext(global::ParserGenerator.Input.SourceContext context)
        {
            return new global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding(Name, Type, context);
        }

        global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode global::System.Collections.Generic.IReadOnlyList<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return Name;
                    case 1:
                        return Type;
                    default:
                        {
                            if (i < 0)
                                throw new global::System.ArgumentOutOfRangeException(nameof(i), string.Format(global::ParserGenerator.SR.ArgumentMustBeNonNegative, nameof(i)));
                            throw new global::System.ArgumentOutOfRangeException(nameof(i));
                        }
                }
            }
        }

        global::System.Collections.Generic.IEnumerator<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode> global::System.Collections.Generic.IEnumerable<global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNode>.GetEnumerator()
        {
            yield return Name;
            yield return Type;
        }

        public sealed override void AcceptSyntaxTreeNodeWriter(global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter v, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            v.WriteTypeSubstitutionVariableBinding(this, writer);
        }

        public sealed override void AcceptSyntaxTreeNodeWalker(global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWalker v)
        {
            if (v == null)
                throw new global::System.ArgumentNullException(nameof(v));
            v.WalkTypeSubstitutionVariableBinding(this);
        }
    }

    public partial interface ISyntaxTreeNodeWriter
    {
        void WriteIdentifier(global::ParserGenerator.Languages.LocalTypeInference.Identifier n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteIntLiteral(global::ParserGenerator.Languages.LocalTypeInference.IntLiteral n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteParameter(global::ParserGenerator.Languages.LocalTypeInference.Parameter n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteParameterList(global::ParserGenerator.Languages.LocalTypeInference.ParameterList n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteArgumentList(global::ParserGenerator.Languages.LocalTypeInference.ArgumentList n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteTypeParameter(global::ParserGenerator.Languages.LocalTypeInference.TypeParameter n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteTypeParameterList(global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteTypeArgumentList(global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteExpression(global::ParserGenerator.Languages.LocalTypeInference.Expression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteExpression(global::ParserGenerator.Languages.LocalTypeInference.Expression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteVariableExpression(global::ParserGenerator.Languages.LocalTypeInference.VariableExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteVariableExpression(global::ParserGenerator.Languages.LocalTypeInference.VariableExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteFalseExpression(global::ParserGenerator.Languages.LocalTypeInference.FalseExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteFalseExpression(global::ParserGenerator.Languages.LocalTypeInference.FalseExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteTrueExpression(global::ParserGenerator.Languages.LocalTypeInference.TrueExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteTrueExpression(global::ParserGenerator.Languages.LocalTypeInference.TrueExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteIntLiteralExpression(global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteIntLiteralExpression(global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteGroupExpression(global::ParserGenerator.Languages.LocalTypeInference.GroupExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteGroupExpression(global::ParserGenerator.Languages.LocalTypeInference.GroupExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteUnaryExpression(global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteUnaryExpression(global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteBinaryExpression(global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteBinaryExpression(global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteFunctionExpression(global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteFunctionExpression(global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteCallExpression(global::ParserGenerator.Languages.LocalTypeInference.CallExpression n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteCallExpression(global::ParserGenerator.Languages.LocalTypeInference.CallExpression n, global::ParserGenerator.Output.IndentedWriter writer, int d);
        void WriteUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.UnaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WritePositiveUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteNegativeUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteLogicalNotUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.BinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteAddBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteSubtractBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteMultiplyBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteDivideBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteModuloBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteEqualToBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteNotEqualToBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteLessThanBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteLessEqualBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteGreaterThanBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteGreaterEqualBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteLogicalAndBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteLogicalOrBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteType(global::ParserGenerator.Languages.LocalTypeInference.Type n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteVariableType(global::ParserGenerator.Languages.LocalTypeInference.VariableType n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteObjectType(global::ParserGenerator.Languages.LocalTypeInference.ObjectType n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteNullType(global::ParserGenerator.Languages.LocalTypeInference.NullType n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteBoolType(global::ParserGenerator.Languages.LocalTypeInference.BoolType n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteIntType(global::ParserGenerator.Languages.LocalTypeInference.IntType n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteFunctionType(global::ParserGenerator.Languages.LocalTypeInference.FunctionType n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.VariableBinding n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteValueVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteTypeVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding n, global::ParserGenerator.Output.IndentedWriter writer);
        void WriteTypeSubstitutionVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding n, global::ParserGenerator.Output.IndentedWriter writer);
    }

    [global::System.Serializable]
    public partial class SyntaxTreeNodeWriter : global::ParserGenerator.Languages.LocalTypeInference.ISyntaxTreeNodeWriter
    {
        public static global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter Instance { get; } = new global::ParserGenerator.Languages.LocalTypeInference.SyntaxTreeNodeWriter();

        public virtual void WriteExpression(global::ParserGenerator.Languages.LocalTypeInference.Expression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteExpression(n, writer, -1);
        }

        public virtual void WriteExpression(global::ParserGenerator.Languages.LocalTypeInference.Expression n, global::ParserGenerator.Output.IndentedWriter writer, int d)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            n.AcceptSyntaxTreeNodeWriter(this, writer, d);
        }

        public virtual void WriteVariableExpression(global::ParserGenerator.Languages.LocalTypeInference.VariableExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteVariableExpression(n, writer, -1);
        }

        public virtual void WriteFalseExpression(global::ParserGenerator.Languages.LocalTypeInference.FalseExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteFalseExpression(n, writer, -1);
        }

        public virtual void WriteTrueExpression(global::ParserGenerator.Languages.LocalTypeInference.TrueExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteTrueExpression(n, writer, -1);
        }

        public virtual void WriteIntLiteralExpression(global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteIntLiteralExpression(n, writer, -1);
        }

        public virtual void WriteGroupExpression(global::ParserGenerator.Languages.LocalTypeInference.GroupExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteGroupExpression(n, writer, -1);
        }

        public virtual void WriteUnaryExpression(global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteUnaryExpression(n, writer, -1);
        }

        public virtual void WriteBinaryExpression(global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteBinaryExpression(n, writer, -1);
        }

        public virtual void WriteFunctionExpression(global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteFunctionExpression(n, writer, -1);
        }

        public virtual void WriteCallExpression(global::ParserGenerator.Languages.LocalTypeInference.CallExpression n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            WriteCallExpression(n, writer, -1);
        }

        public virtual void WriteUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.UnaryOp n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            n.AcceptSyntaxTreeNodeWriter(this, writer);
        }

        public virtual void WriteBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.BinaryOp n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            n.AcceptSyntaxTreeNodeWriter(this, writer);
        }

        public virtual void WriteType(global::ParserGenerator.Languages.LocalTypeInference.Type n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            n.AcceptSyntaxTreeNodeWriter(this, writer);
        }

        public virtual void WriteVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.VariableBinding n, global::ParserGenerator.Output.IndentedWriter writer)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            if (writer == null)
                throw new global::System.ArgumentNullException(nameof(writer));
            n.AcceptSyntaxTreeNodeWriter(this, writer);
        }
    }

    [global::System.Serializable]
    public partial class SyntaxTreeNodeWalker
    {
        public virtual void EnterIdentifier(global::ParserGenerator.Languages.LocalTypeInference.Identifier n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveIdentifier(global::ParserGenerator.Languages.LocalTypeInference.Identifier n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkIdentifier(global::ParserGenerator.Languages.LocalTypeInference.Identifier n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterIdentifier(n);
            LeaveIdentifier(n);
        }

        public virtual void EnterIntLiteral(global::ParserGenerator.Languages.LocalTypeInference.IntLiteral n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveIntLiteral(global::ParserGenerator.Languages.LocalTypeInference.IntLiteral n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkIntLiteral(global::ParserGenerator.Languages.LocalTypeInference.IntLiteral n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterIntLiteral(n);
            LeaveIntLiteral(n);
        }

        public virtual void EnterParameter(global::ParserGenerator.Languages.LocalTypeInference.Parameter n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveParameter(global::ParserGenerator.Languages.LocalTypeInference.Parameter n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkParameter(global::ParserGenerator.Languages.LocalTypeInference.Parameter n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterParameter(n);
            WalkIdentifier(n.Name);
            WalkType(n.Type);
            LeaveParameter(n);
        }

        public virtual void EnterParameterList(global::ParserGenerator.Languages.LocalTypeInference.ParameterList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveParameterList(global::ParserGenerator.Languages.LocalTypeInference.ParameterList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkParameterList(global::ParserGenerator.Languages.LocalTypeInference.ParameterList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterParameterList(n);
            foreach (var child in n.Items)
                WalkParameter(child);
            LeaveParameterList(n);
        }

        public virtual void EnterArgumentList(global::ParserGenerator.Languages.LocalTypeInference.ArgumentList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveArgumentList(global::ParserGenerator.Languages.LocalTypeInference.ArgumentList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkArgumentList(global::ParserGenerator.Languages.LocalTypeInference.ArgumentList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterArgumentList(n);
            foreach (var child in n.Items)
                WalkExpression(child);
            LeaveArgumentList(n);
        }

        public virtual void EnterTypeParameter(global::ParserGenerator.Languages.LocalTypeInference.TypeParameter n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveTypeParameter(global::ParserGenerator.Languages.LocalTypeInference.TypeParameter n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkTypeParameter(global::ParserGenerator.Languages.LocalTypeInference.TypeParameter n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterTypeParameter(n);
            WalkIdentifier(n.Name);
            LeaveTypeParameter(n);
        }

        public virtual void EnterTypeParameterList(global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveTypeParameterList(global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkTypeParameterList(global::ParserGenerator.Languages.LocalTypeInference.TypeParameterList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterTypeParameterList(n);
            foreach (var child in n.Items)
                WalkTypeParameter(child);
            LeaveTypeParameterList(n);
        }

        public virtual void EnterTypeArgumentList(global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveTypeArgumentList(global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkTypeArgumentList(global::ParserGenerator.Languages.LocalTypeInference.TypeArgumentList n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterTypeArgumentList(n);
            foreach (var child in n.Items)
                WalkType(child);
            LeaveTypeArgumentList(n);
        }

        public virtual void WalkExpression(global::ParserGenerator.Languages.LocalTypeInference.Expression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            n.AcceptSyntaxTreeNodeWalker(this);
        }

        public virtual void EnterVariableExpression(global::ParserGenerator.Languages.LocalTypeInference.VariableExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveVariableExpression(global::ParserGenerator.Languages.LocalTypeInference.VariableExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkVariableExpression(global::ParserGenerator.Languages.LocalTypeInference.VariableExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterVariableExpression(n);
            WalkIdentifier(n.Name);
            LeaveVariableExpression(n);
        }

        public virtual void EnterFalseExpression(global::ParserGenerator.Languages.LocalTypeInference.FalseExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveFalseExpression(global::ParserGenerator.Languages.LocalTypeInference.FalseExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkFalseExpression(global::ParserGenerator.Languages.LocalTypeInference.FalseExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterFalseExpression(n);
            LeaveFalseExpression(n);
        }

        public virtual void EnterTrueExpression(global::ParserGenerator.Languages.LocalTypeInference.TrueExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveTrueExpression(global::ParserGenerator.Languages.LocalTypeInference.TrueExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkTrueExpression(global::ParserGenerator.Languages.LocalTypeInference.TrueExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterTrueExpression(n);
            LeaveTrueExpression(n);
        }

        public virtual void EnterIntLiteralExpression(global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveIntLiteralExpression(global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkIntLiteralExpression(global::ParserGenerator.Languages.LocalTypeInference.IntLiteralExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterIntLiteralExpression(n);
            WalkIntLiteral(n.Value);
            LeaveIntLiteralExpression(n);
        }

        public virtual void EnterGroupExpression(global::ParserGenerator.Languages.LocalTypeInference.GroupExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveGroupExpression(global::ParserGenerator.Languages.LocalTypeInference.GroupExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkGroupExpression(global::ParserGenerator.Languages.LocalTypeInference.GroupExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterGroupExpression(n);
            WalkExpression(n.Operand);
            LeaveGroupExpression(n);
        }

        public virtual void EnterUnaryExpression(global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveUnaryExpression(global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkUnaryExpression(global::ParserGenerator.Languages.LocalTypeInference.UnaryExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterUnaryExpression(n);
            WalkUnaryOp(n.Op);
            WalkExpression(n.Operand);
            LeaveUnaryExpression(n);
        }

        public virtual void EnterBinaryExpression(global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveBinaryExpression(global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkBinaryExpression(global::ParserGenerator.Languages.LocalTypeInference.BinaryExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterBinaryExpression(n);
            WalkExpression(n.Left);
            WalkBinaryOp(n.Op);
            WalkExpression(n.Right);
            LeaveBinaryExpression(n);
        }

        public virtual void EnterFunctionExpression(global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveFunctionExpression(global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkFunctionExpression(global::ParserGenerator.Languages.LocalTypeInference.FunctionExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterFunctionExpression(n);
            if (n.TypeParameters != null)
                WalkTypeParameterList(n.TypeParameters);
            WalkParameterList(n.Parameters);
            WalkExpression(n.Body);
            LeaveFunctionExpression(n);
        }

        public virtual void EnterCallExpression(global::ParserGenerator.Languages.LocalTypeInference.CallExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveCallExpression(global::ParserGenerator.Languages.LocalTypeInference.CallExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkCallExpression(global::ParserGenerator.Languages.LocalTypeInference.CallExpression n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterCallExpression(n);
            WalkExpression(n.Function);
            if (n.TypeArguments != null)
                WalkTypeArgumentList(n.TypeArguments);
            WalkArgumentList(n.Arguments);
            LeaveCallExpression(n);
        }

        public virtual void WalkUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.UnaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            n.AcceptSyntaxTreeNodeWalker(this);
        }

        public virtual void EnterPositiveUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeavePositiveUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkPositiveUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.PositiveUnaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterPositiveUnaryOp(n);
            LeavePositiveUnaryOp(n);
        }

        public virtual void EnterNegativeUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveNegativeUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkNegativeUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.NegativeUnaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterNegativeUnaryOp(n);
            LeaveNegativeUnaryOp(n);
        }

        public virtual void EnterLogicalNotUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveLogicalNotUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkLogicalNotUnaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalNotUnaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterLogicalNotUnaryOp(n);
            LeaveLogicalNotUnaryOp(n);
        }

        public virtual void WalkBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.BinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            n.AcceptSyntaxTreeNodeWalker(this);
        }

        public virtual void EnterAddBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveAddBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkAddBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.AddBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterAddBinaryOp(n);
            LeaveAddBinaryOp(n);
        }

        public virtual void EnterSubtractBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveSubtractBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkSubtractBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.SubtractBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterSubtractBinaryOp(n);
            LeaveSubtractBinaryOp(n);
        }

        public virtual void EnterMultiplyBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveMultiplyBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkMultiplyBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.MultiplyBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterMultiplyBinaryOp(n);
            LeaveMultiplyBinaryOp(n);
        }

        public virtual void EnterDivideBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveDivideBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkDivideBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.DivideBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterDivideBinaryOp(n);
            LeaveDivideBinaryOp(n);
        }

        public virtual void EnterModuloBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveModuloBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkModuloBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.ModuloBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterModuloBinaryOp(n);
            LeaveModuloBinaryOp(n);
        }

        public virtual void EnterEqualToBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveEqualToBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkEqualToBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.EqualToBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterEqualToBinaryOp(n);
            LeaveEqualToBinaryOp(n);
        }

        public virtual void EnterNotEqualToBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveNotEqualToBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkNotEqualToBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.NotEqualToBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterNotEqualToBinaryOp(n);
            LeaveNotEqualToBinaryOp(n);
        }

        public virtual void EnterLessThanBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveLessThanBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkLessThanBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LessThanBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterLessThanBinaryOp(n);
            LeaveLessThanBinaryOp(n);
        }

        public virtual void EnterLessEqualBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveLessEqualBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkLessEqualBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LessEqualBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterLessEqualBinaryOp(n);
            LeaveLessEqualBinaryOp(n);
        }

        public virtual void EnterGreaterThanBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveGreaterThanBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkGreaterThanBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.GreaterThanBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterGreaterThanBinaryOp(n);
            LeaveGreaterThanBinaryOp(n);
        }

        public virtual void EnterGreaterEqualBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveGreaterEqualBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkGreaterEqualBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.GreaterEqualBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterGreaterEqualBinaryOp(n);
            LeaveGreaterEqualBinaryOp(n);
        }

        public virtual void EnterLogicalAndBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveLogicalAndBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkLogicalAndBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalAndBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterLogicalAndBinaryOp(n);
            LeaveLogicalAndBinaryOp(n);
        }

        public virtual void EnterLogicalOrBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveLogicalOrBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkLogicalOrBinaryOp(global::ParserGenerator.Languages.LocalTypeInference.LogicalOrBinaryOp n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterLogicalOrBinaryOp(n);
            LeaveLogicalOrBinaryOp(n);
        }

        public virtual void WalkType(global::ParserGenerator.Languages.LocalTypeInference.Type n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            n.AcceptSyntaxTreeNodeWalker(this);
        }

        public virtual void EnterVariableType(global::ParserGenerator.Languages.LocalTypeInference.VariableType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveVariableType(global::ParserGenerator.Languages.LocalTypeInference.VariableType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkVariableType(global::ParserGenerator.Languages.LocalTypeInference.VariableType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterVariableType(n);
            WalkIdentifier(n.Name);
            LeaveVariableType(n);
        }

        public virtual void EnterObjectType(global::ParserGenerator.Languages.LocalTypeInference.ObjectType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveObjectType(global::ParserGenerator.Languages.LocalTypeInference.ObjectType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkObjectType(global::ParserGenerator.Languages.LocalTypeInference.ObjectType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterObjectType(n);
            LeaveObjectType(n);
        }

        public virtual void EnterNullType(global::ParserGenerator.Languages.LocalTypeInference.NullType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveNullType(global::ParserGenerator.Languages.LocalTypeInference.NullType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkNullType(global::ParserGenerator.Languages.LocalTypeInference.NullType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterNullType(n);
            LeaveNullType(n);
        }

        public virtual void EnterBoolType(global::ParserGenerator.Languages.LocalTypeInference.BoolType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveBoolType(global::ParserGenerator.Languages.LocalTypeInference.BoolType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkBoolType(global::ParserGenerator.Languages.LocalTypeInference.BoolType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterBoolType(n);
            LeaveBoolType(n);
        }

        public virtual void EnterIntType(global::ParserGenerator.Languages.LocalTypeInference.IntType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveIntType(global::ParserGenerator.Languages.LocalTypeInference.IntType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkIntType(global::ParserGenerator.Languages.LocalTypeInference.IntType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterIntType(n);
            LeaveIntType(n);
        }

        public virtual void EnterFunctionType(global::ParserGenerator.Languages.LocalTypeInference.FunctionType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveFunctionType(global::ParserGenerator.Languages.LocalTypeInference.FunctionType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkFunctionType(global::ParserGenerator.Languages.LocalTypeInference.FunctionType n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterFunctionType(n);
            if (n.TypeParameters != null)
                WalkTypeParameterList(n.TypeParameters);
            foreach (var child in n.Sources)
                WalkType(child);
            WalkType(n.Target);
            LeaveFunctionType(n);
        }

        public virtual void WalkVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.VariableBinding n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            n.AcceptSyntaxTreeNodeWalker(this);
        }

        public virtual void EnterValueVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveValueVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkValueVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.ValueVariableBinding n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterValueVariableBinding(n);
            WalkIdentifier(n.Name);
            WalkType(n.Type);
            LeaveValueVariableBinding(n);
        }

        public virtual void EnterTypeVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveTypeVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkTypeVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.TypeVariableBinding n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterTypeVariableBinding(n);
            WalkIdentifier(n.Name);
            LeaveTypeVariableBinding(n);
        }

        public virtual void EnterTypeSubstitutionVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void LeaveTypeSubstitutionVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
        }

        public virtual void WalkTypeSubstitutionVariableBinding(global::ParserGenerator.Languages.LocalTypeInference.TypeSubstitutionVariableBinding n)
        {
            if (n == null)
                throw new global::System.ArgumentNullException(nameof(n));
            EnterTypeSubstitutionVariableBinding(n);
            WalkIdentifier(n.Name);
            WalkType(n.Type);
            LeaveTypeSubstitutionVariableBinding(n);
        }
    }
}

namespace ParserGenerator.Languages.LocalTypeInference
{
    using ParserGenerator.Collections;

    [global::System.Serializable]
    public sealed partial class LocalTypeInferenceProgramParser
    {
        private int _currentStart;
        private readonly global::System.Collections.Generic.Stack<int> _savedStarts = new global::System.Collections.Generic.Stack<int>();
        private global::ParserGenerator.Input.SourceContext _nodeContext;
        private readonly global::System.Collections.Generic.List<int> _states = new global::System.Collections.Generic.List<int>();
        private readonly global::System.Collections.Generic.List<string> _symbols = new global::System.Collections.Generic.List<string>();
        private readonly global::System.Collections.Generic.List<object> _values = new global::System.Collections.Generic.List<object>();
        private readonly global::System.Collections.Generic.List<global::ParserGenerator.Input.SourceContext> _contexts = new global::System.Collections.Generic.List<global::ParserGenerator.Input.SourceContext>();

        public global::ParserGenerator.Input.SourceReader Reader { get; private set; }
        public global::ParserGenerator.Input.SourceLocation TokenBegin { get; private set; }
        public global::ParserGenerator.Input.SourceLocation TokenEnd { get; private set; }
        public global::ParserGenerator.Input.SourceContext TokenContext { get; private set; }
        public object TokenValue { get; private set; }
        public int Level { get; private set; }

        public const int NoneTokenTag = 0;
        public const int IdentifierTokenTag = 9;
        public const int IntLiteralTokenTag = 10;

        public LocalTypeInferenceProgramParser()
            : this(global::ParserGenerator.Input.SourceReader.FromConsole())
        {
        }

        public LocalTypeInferenceProgramParser(global::ParserGenerator.Input.SourceReader reader)
        {
            if (reader == null)
                throw new global::System.ArgumentNullException(nameof(reader));
            Reader = reader;
            TokenBegin = TokenEnd = Reader.Location;
        }

        private void PushStart(int start)
        {
            _savedStarts.Push(_currentStart);
            _currentStart = start;
        }

        private void GotoStart(int start)
        {
            _currentStart = start;
        }

        private void PopStart()
        {
            _currentStart = _savedStarts.Pop();
        }

        public global::ParserGenerator.Exceptions.SyntaxErrorException SyntaxError(string message, global::ParserGenerator.Input.SourceLocation location)
        {
            if (message == null)
                throw new global::System.ArgumentNullException(nameof(message));
            global::ParserGenerator.Exceptions.SyntaxErrorException e = new global::ParserGenerator.Exceptions.SyntaxErrorException(message);
            e.AddLocation(location);
            return e;
        }

        public global::ParserGenerator.Exceptions.SyntaxErrorException SyntaxError(string message, global::ParserGenerator.Input.SourceContext context)
        {
            if (message == null)
                throw new global::System.ArgumentNullException(nameof(message));
            if (context == null)
                throw new global::System.ArgumentNullException(nameof(context));
            return SyntaxError(message, context.Begin);
        }

        public global::ParserGenerator.Exceptions.SyntaxErrorException SyntaxError(string message)
        {
            if (message == null)
                throw new global::System.ArgumentNullException(nameof(message));
            return SyntaxError(message, Reader.Location);
        }

        private static readonly string[] _starts =
        {
            "DEFAULT"
        };

        private static readonly string[] _tokens =
        {
            "None",
            "'def'",
            "'object'",
            "'null'",
            "'bool'",
            "'int'",
            "'forall'",
            "'false'",
            "'true'",
            "Identifier",
            "IntLiteral",
            "':'",
            "','",
            "'('",
            "')'",
            "'{'",
            "'}'",
            "'['",
            "']'",
            "'+'",
            "'-'",
            "'!'",
            "'*'",
            "'/'",
            "'%'",
            "'<'",
            "'<='",
            "'>'",
            "'>='",
            "'=='",
            "'!='",
            "'&&'",
            "'||'",
            "'->'",
            "'.'",
            "'?'",
            "'<:'",
            "'\\\\/'",
            "'/\\\\'"
        };

        private static readonly int[] _start =
        {
            0x00, 0x00, 0x00
        };

        private static readonly int[] _flag =
        {
            0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
            0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
            0x0155, 0x0155, 0x0000, 0x0000, 0x0175, 0x0175, 0x0000, 0x0000,
            0x0000, 0x0000, 0x0195, 0x0195, 0x0000, 0x0000, 0x0145, 0x0145,
            0x01B5, 0x01B5, 0x0185, 0x0185, 0x00D5, 0x00D5, 0x00E5, 0x00E5,
            0x0165, 0x0165, 0x00C5, 0x00C5, 0x0225, 0x0225, 0x00B5, 0x00B5,
            0x0235, 0x0235, 0x0115, 0x0115, 0x0125, 0x0125, 0x00F5, 0x00F5,
            0x0105, 0x0105, 0x0135, 0x0135, 0x0131, 0x0131, 0x0141, 0x0141,
            0x0001, 0x0001, 0x0151, 0x0151, 0x0001, 0x0001, 0x0001, 0x0001,
            0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
            0x0001, 0x0001, 0x0001, 0x0001, 0x01E5, 0x01E5, 0x01F5, 0x01F5,
            0x0265, 0x0265, 0x0255, 0x0255, 0x0205, 0x0205, 0x0245, 0x0245,
            0x01A5, 0x01A5, 0x01D5, 0x01D5, 0x0215, 0x0215, 0x01C5, 0x01C5,
            0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
            0x0001, 0x0001, 0x0001, 0x0001, 0x0015, 0x0015, 0x0055, 0x0055,
            0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0045, 0x0045,
            0x0035, 0x0035, 0x0085, 0x0085, 0x0001, 0x0001, 0x0075, 0x0075,
            0x0001, 0x0001, 0x0065, 0x0065, 0x0025, 0x0025
        };

        private static readonly int[] _fast =
        {
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x01, 0x03, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00,
            0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
            0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
            0x0E, 0x0E, 0x0F, 0x00, 0x10, 0x11, 0x12, 0x13,
            0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
            0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
            0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
            0x14, 0x14, 0x14, 0x15, 0x16, 0x17, 0x00, 0x14,
            0x00, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x14,
            0x14, 0x1E, 0x1F, 0x14, 0x20, 0x14, 0x21, 0x22,
            0x14, 0x14, 0x23, 0x24, 0x25, 0x26, 0x14, 0x14,
            0x14, 0x14, 0x14, 0x27, 0x28, 0x29, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        };

        private static readonly int[] _first =
        {
            0x0000, 0x0009, 0x000A, 0x000E, 0x0020, 0x0021, 0x0022, 0x0025,
            0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D,
            0x002E, 0x002F, 0x0030, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E,
            0x003F, 0x0040, 0x0041, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
            0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
            0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
            0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x007B, 0x007C, 0x007D,
            0x007E, 0x0085, 0x0086, 0x00A0, 0x00A1, 0x2000, 0x200B, 0x2028,
            0x202A, 0x202F, 0x2030, 0x205F, 0x2060, 0x3000, 0x3001
        };

        private static readonly int[] _last =
        {
            0x00000008, 0x00000009, 0x0000000D, 0x0000001F,
            0x00000020, 0x00000021, 0x00000024, 0x00000025,
            0x00000026, 0x00000027, 0x00000028, 0x00000029,
            0x0000002A, 0x0000002B, 0x0000002C, 0x0000002D,
            0x0000002E, 0x0000002F, 0x00000039, 0x0000003A,
            0x0000003B, 0x0000003C, 0x0000003D, 0x0000003E,
            0x0000003F, 0x00000040, 0x0000005A, 0x0000005B,
            0x0000005C, 0x0000005D, 0x0000005E, 0x0000005F,
            0x00000060, 0x00000061, 0x00000062, 0x00000063,
            0x00000064, 0x00000065, 0x00000066, 0x00000068,
            0x00000069, 0x0000006A, 0x0000006B, 0x0000006C,
            0x0000006D, 0x0000006E, 0x0000006F, 0x00000071,
            0x00000072, 0x00000073, 0x00000074, 0x00000075,
            0x0000007A, 0x0000007B, 0x0000007C, 0x0000007D,
            0x00000084, 0x00000085, 0x0000009F, 0x000000A0,
            0x00001FFF, 0x0000200A, 0x00002027, 0x00002029,
            0x0000202E, 0x0000202F, 0x0000205E, 0x0000205F,
            0x00002FFF, 0x00003000, 0x0010FFFF
        };

        private static readonly int[] _map =
        {
            0x00, 0x01, 0x02, 0x00, 0x01, 0x03, 0x00, 0x04,
            0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
            0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x10, 0x11, 0x12,
            0x13, 0x00, 0x14, 0x15, 0x16, 0x17, 0x00, 0x14,
            0x00, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x14,
            0x1E, 0x1F, 0x14, 0x20, 0x14, 0x21, 0x22, 0x14,
            0x23, 0x24, 0x25, 0x26, 0x14, 0x27, 0x28, 0x29,
            0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02,
            0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00
        };

        private static readonly int[] _sbase =
        {
            0x0000, 0x0210, 0x0229, 0x0242, 0x025B, 0x0274, 0x028D, 0x02A6,
            0x0021, 0x0040, 0x002E, 0x003A, 0x0009, 0x001D, 0x001E, 0x001B,
            0x001A, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
            0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0045,
            0x001C, 0x0025, 0x012F, 0x01F7, 0x0035, 0x004E, 0x0067, 0x0080,
            0x0099, 0x00B2, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
            0x0001, 0x0001, 0x0001, 0x0001, 0x00CB, 0x00E4, 0x00FD, 0x0116,
            0x0148, 0x01DE, 0x001C, 0x001C, 0x0161, 0x017A, 0x0193, 0x001C,
            0x001C, 0x001C, 0x01AC, 0x001C, 0x01C5, 0x001C, 0x001C
        };

        private static readonly int[] _scheck =
        {
            0x2A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
            0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
            0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
            0x28, 0x29, 0x0E, 0x11, 0x0F, 0x12, 0x11, 0x11,
            0x14, 0x28, 0x11, 0x0E, 0x18, 0x19, 0x1A, 0x1B,
            0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
            0x24, 0x25, 0x26, 0x0E, 0x16, 0x05, 0x01, 0x0D,
            0x2A, 0x14, 0x2A, 0x2A, 0x2A, 0x18, 0x19, 0x1A,
            0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
            0x23, 0x24, 0x25, 0x26, 0x0E, 0x2A, 0x2A, 0x2A,
            0x2A, 0x2A, 0x14, 0x2A, 0x2A, 0x2A, 0x18, 0x19,
            0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21,
            0x22, 0x23, 0x24, 0x25, 0x26, 0x0E, 0x2A, 0x2A,
            0x2A, 0x2A, 0x2A, 0x14, 0x2A, 0x2A, 0x2A, 0x18,
            0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x0E, 0x2A,
            0x2A, 0x2A, 0x2A, 0x2A, 0x14, 0x2A, 0x2A, 0x2A,
            0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
            0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x0E,
            0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x14, 0x2A, 0x2A,
            0x2A, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
            0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
            0x0E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x14, 0x2A,
            0x2A, 0x2A, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
            0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
            0x26, 0x0E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x14,
            0x2A, 0x2A, 0x2A, 0x18, 0x19, 0x1A, 0x1B, 0x1C,
            0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
            0x25, 0x26, 0x0E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
            0x14, 0x2A, 0x2A, 0x2A, 0x18, 0x19, 0x1A, 0x1B,
            0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
            0x24, 0x25, 0x26, 0x0E, 0x2A, 0x2A, 0x2A, 0x2A,
            0x2A, 0x14, 0x2A, 0x2A, 0x2A, 0x18, 0x19, 0x1A,
            0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
            0x23, 0x24, 0x25, 0x26, 0x0E, 0x2A, 0x2A, 0x2A,
            0x2A, 0x2A, 0x14, 0x2A, 0x2A, 0x2A, 0x18, 0x19,
            0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21,
            0x22, 0x23, 0x24, 0x25, 0x26, 0x0E, 0x2A, 0x2A,
            0x2A, 0x2A, 0x2A, 0x14, 0x2A, 0x2A, 0x2A, 0x18,
            0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x0E, 0x2A,
            0x2A, 0x2A, 0x2A, 0x2A, 0x14, 0x2A, 0x2A, 0x2A,
            0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
            0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x0E,
            0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x14, 0x2A, 0x2A,
            0x2A, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
            0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
            0x0E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x14, 0x2A,
            0x2A, 0x2A, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
            0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
            0x26, 0x0E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x14,
            0x2A, 0x2A, 0x2A, 0x18, 0x19, 0x1A, 0x1B, 0x1C,
            0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
            0x25, 0x26, 0x0E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
            0x14, 0x2A, 0x2A, 0x2A, 0x18, 0x19, 0x1A, 0x1B,
            0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
            0x24, 0x25, 0x26, 0x0E, 0x2A, 0x2A, 0x2A, 0x2A,
            0x2A, 0x14, 0x2A, 0x2A, 0x2A, 0x18, 0x19, 0x1A,
            0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
            0x23, 0x24, 0x25, 0x26, 0x0E, 0x2A, 0x2A, 0x2A,
            0x2A, 0x2A, 0x14, 0x2A, 0x2A, 0x2A, 0x18, 0x19,
            0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21,
            0x22, 0x23, 0x24, 0x25, 0x26, 0x0E, 0x2A, 0x2A,
            0x2A, 0x2A, 0x2A, 0x14, 0x2A, 0x2A, 0x2A, 0x18,
            0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x0E, 0x2A,
            0x2A, 0x2A, 0x2A, 0x2A, 0x14, 0x2A, 0x2A, 0x2A,
            0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
            0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x0E,
            0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x14, 0x2A, 0x2A,
            0x2A, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
            0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
            0x0E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x14, 0x2A,
            0x2A, 0x2A, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
            0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
            0x26, 0x0E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x14,
            0x2A, 0x2A, 0x2A, 0x18, 0x19, 0x1A, 0x1B, 0x1C,
            0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
            0x25, 0x26, 0x0E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
            0x14, 0x2A, 0x2A, 0x2A, 0x18, 0x19, 0x1A, 0x1B,
            0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
            0x24, 0x25, 0x26, 0x0E, 0x2A, 0x2A, 0x2A, 0x2A,
            0x2A, 0x14, 0x2A, 0x2A, 0x2A, 0x18, 0x19, 0x1A,
            0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
            0x23, 0x24, 0x25, 0x26, 0x0E, 0x2A, 0x2A, 0x2A,
            0x2A, 0x2A, 0x14, 0x2A, 0x2A, 0x2A, 0x18, 0x19,
            0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21,
            0x22, 0x23, 0x24, 0x25, 0x26, 0x2A, 0x2A, 0x2A
        };

        private static readonly int[] _svalue =
        {
            0x00, 0x1F, 0x1E, 0x08, 0x11, 0x09, 0x12, 0x13,
            0x14, 0x1D, 0x15, 0x0F, 0x16, 0x0A, 0x21, 0x17,
            0x0D, 0x0E, 0x10, 0x18, 0x20, 0x19, 0x0B, 0x1A,
            0x20, 0x03, 0x20, 0x06, 0x20, 0x01, 0x07, 0x20,
            0x20, 0x04, 0x02, 0x20, 0x20, 0x05, 0x20, 0x1B,
            0x0C, 0x1C, 0x20, 0x33, 0x2F, 0x32, 0x30, 0x31,
            0x20, 0x2E, 0x2A, 0x21, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x2C, 0x2B, 0x1F, 0x2D,
            0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x36, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x37, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x39, 0x20,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
            0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
            0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3B,
            0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
            0x00, 0x00, 0x00, 0x3C, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x3D, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20,
            0x20, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3F, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x34, 0x20, 0x20, 0x20, 0x20, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
            0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x42, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
            0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x43, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
            0x00, 0x00, 0x00, 0x20, 0x20, 0x44, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x45, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x46, 0x20, 0x20, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20,
            0x20, 0x20, 0x41, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x35,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
            0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
            0x00, 0x20, 0x24, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
            0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x25, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
            0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x26, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27,
            0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20,
            0x20, 0x28, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x29,
            0x20, 0x20, 0x20, 0x20, 0x20
        };

        private static readonly string[] _goals =
        {
            "Expression",
            "InteractiveTypeChecking"
        };

        private static readonly string[] _nonterminals =
        {
            "Parameter",
            "ParameterList",
            "ArgumentList",
            "TypeParameter",
            "TypeParameterList",
            "TypeArgumentList",
            "PrimaryExpression",
            "UnaryExpression",
            "MultiplicativeExpression",
            "AdditiveExpression",
            "RelationalExpression",
            "EqualityExpression",
            "LogicalAndExpression",
            "LogicalOrExpression",
            "Expression",
            "PrimaryType",
            "Type",
            "InteractiveTypeChecking",
            "Expression'",
            "InteractiveTypeChecking'",
            "ParameterList'",
            "ExpressionList",
            "TypeParameterList'",
            "TypeList",
            "PrimaryTypeList"
        };

        private static readonly string[] _text =
        {
            "end marker",
            "'def'",
            "'object'",
            "'null'",
            "'bool'",
            "'int'",
            "'forall'",
            "'false'",
            "'true'",
            "identifier",
            "int literal",
            "':'",
            "','",
            "'('",
            "')'",
            "'{'",
            "'}'",
            "'['",
            "']'",
            "'+'",
            "'-'",
            "'!'",
            "'*'",
            "'/'",
            "'%'",
            "'<'",
            "'<='",
            "'>'",
            "'>='",
            "'=='",
            "'!='",
            "'&&'",
            "'||'",
            "'->'",
            "'.'",
            "'?'",
            "'<:'",
            "'\\\\/'",
            "'/\\\\'"
        };

        private static readonly int[] _goal =
        {
            0x00, 0x01
        };

        private static readonly int[] _left =
        {
            0x12, 0x13, 0x00, 0x01, 0x14, 0x14, 0x02, 0x15,
            0x15, 0x03, 0x04, 0x16, 0x16, 0x05, 0x17, 0x17,
            0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
            0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08,
            0x08, 0x09, 0x09, 0x09, 0x0A, 0x0A, 0x0A, 0x0A,
            0x0A, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0D, 0x0D,
            0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10,
            0x10, 0x18, 0x18, 0x10, 0x11, 0x11, 0x11, 0x11
        };

        private static readonly int[] _length =
        {
            0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x01, 0x01,
            0x03, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03,
            0x01, 0x01, 0x01, 0x01, 0x07, 0x0A, 0x03, 0x04,
            0x07, 0x01, 0x02, 0x02, 0x02, 0x01, 0x03, 0x03,
            0x03, 0x01, 0x03, 0x03, 0x01, 0x03, 0x03, 0x03,
            0x03, 0x01, 0x03, 0x03, 0x01, 0x03, 0x01, 0x03,
            0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01,
            0x03, 0x01, 0x03, 0x06, 0x04, 0x04, 0x04, 0x01
        };

        private static readonly int[] _pbase =
        {
            0x0418, 0x01B3, 0x0015, 0x00B6, 0x03F5, 0x040A, 0x03D1, 0x0368,
            0x0296, 0x0353, 0x0257, 0x0418, 0x0418, 0x0418, 0x026C, 0x0281,
            0x0242, 0x022D, 0x0073, 0x0418, 0x000A, 0x042C, 0x0007, 0x0418,
            0x0418, 0x0418, 0x0418, 0x0418, 0x0418, 0x0418, 0x0418, 0x0418,
            0x0418, 0x0418, 0x0418, 0x0418, 0x0418, 0x042C, 0x02EA, 0x02D5,
            0x033E, 0x00C1, 0x0008, 0x00C4, 0x0087, 0x0128, 0x0013, 0x0008,
            0x017F, 0x0176, 0x0158, 0x014F, 0x0131, 0x042C, 0x03D4, 0x03D7,
            0x03EC, 0x03F2, 0x0392, 0x03BC, 0x03A7, 0x037D, 0x02AB, 0x02C0,
            0x02FF, 0x0314, 0x0329, 0x0028, 0x00C5, 0x0093, 0x00D2, 0x0050,
            0x0004, 0x0090, 0x00B1, 0x0088, 0x003F, 0x003B, 0x0029, 0x006C,
            0x00B5, 0x01C4, 0x042C, 0x042C, 0x042C, 0x042C, 0x0438, 0x000D,
            0x004D, 0x01D9, 0x0418, 0x0083, 0x042C, 0x00A3, 0x00C1, 0x042C,
            0x00D1, 0x0008, 0x00DD, 0x00DB, 0x00E2, 0x00D5, 0x0012, 0x0438,
            0x019D, 0x00C2, 0x0418, 0x006A, 0x0418, 0x0096, 0x0006, 0x00C1,
            0x006B, 0x0016, 0x004A, 0x00A9, 0x00AC, 0x00B7, 0x042C, 0x01EE,
            0x0203, 0x00AF, 0x00A7, 0x0418, 0x00C9, 0x0218, 0x0001, 0x0002,
            0x0003, 0x003A, 0x004B, 0x0084, 0x0000, 0x0025, 0x0039, 0x006E,
            0x004E, 0x0082, 0x0097, 0x009C, 0x00B0, 0x00BA, 0x00D0, 0x000E,
            0x000B, 0x000B, 0x0005, 0x0009, 0x0034, 0x0054, 0x00CB
        };

        private static readonly int[] _pcheck =
        {
            0x00, 0x01, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00,
            0x7E, 0x7E, 0x00, 0x0B, 0x0C, 0x0D, 0x7E, 0x01,
            0x0C, 0x09, 0x0C, 0x13, 0x0E, 0x00, 0x12, 0x17,
            0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
            0x20, 0x21, 0x22, 0x23, 0x24, 0x00, 0x01, 0x24,
            0x16, 0x16, 0x29, 0x29, 0x16, 0x24, 0x29, 0x22,
            0x0B, 0x0C, 0x0D, 0x21, 0x21, 0x0C, 0x0E, 0x21,
            0x13, 0x00, 0x01, 0x12, 0x17, 0x18, 0x19, 0x1A,
            0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
            0x23, 0x24, 0x0B, 0x22, 0x13, 0x12, 0x00, 0x01,
            0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
            0x1F, 0x20, 0x5A, 0x0E, 0x0C, 0x24, 0x2A, 0x5E,
            0x16, 0x13, 0x12, 0x2F, 0x2A, 0x17, 0x18, 0x19,
            0x1A, 0x2F, 0x6A, 0x21, 0x6C, 0x6A, 0x00, 0x01,
            0x6F, 0x6F, 0x24, 0x6A, 0x6F, 0x2A, 0x0C, 0x0C,
            0x0C, 0x25, 0x2F, 0x7B, 0x12, 0x12, 0x12, 0x5A,
            0x0D, 0x13, 0x00, 0x01, 0x11, 0x17, 0x18, 0x19,
            0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x22, 0x22, 0x6A,
            0x0D, 0x6C, 0x24, 0x5A, 0x0C, 0x13, 0x0E, 0x00,
            0x01, 0x17, 0x18, 0x61, 0x00, 0x01, 0x0E, 0x0C,
            0x7B, 0x0E, 0x0C, 0x6A, 0x0E, 0x6C, 0x24, 0x00,
            0x5A, 0x25, 0x13, 0x24, 0x25, 0x26, 0x17, 0x13,
            0x00, 0x01, 0x0F, 0x0C, 0x7B, 0x0E, 0x00, 0x0E,
            0x6A, 0x12, 0x6C, 0x24, 0x10, 0x0C, 0x0F, 0x0E,
            0x24, 0x0C, 0x0C, 0x13, 0x0E, 0x0E, 0x10, 0x12,
            0x5A, 0x7B, 0x09, 0x24, 0x25, 0x26, 0x0C, 0x15,
            0x0E, 0x0C, 0x0E, 0x0E, 0x24, 0x00, 0x20, 0x22,
            0x6A, 0x10, 0x6C, 0x00, 0x5A, 0x00, 0x0D, 0x25,
            0x15, 0x0C, 0x00, 0x0E, 0x12, 0x15, 0x7E, 0x12,
            0x7E, 0x7B, 0x7E, 0x7E, 0x6A, 0x7E, 0x6C, 0x35,
            0x25, 0x5A, 0x7E, 0x7E, 0x7E, 0x25, 0x5A, 0x7E,
            0x7E, 0x24, 0x25, 0x26, 0x7E, 0x7B, 0x7E, 0x7E,
            0x35, 0x6A, 0x7E, 0x6C, 0x7E, 0x35, 0x6A, 0x7E,
            0x6C, 0x7E, 0x5A, 0x7E, 0x52, 0x53, 0x54, 0x55,
            0x56, 0x7E, 0x7B, 0x7E, 0x7E, 0x7E, 0x5C, 0x7B,
            0x7E, 0x5F, 0x6A, 0x7E, 0x6C, 0x52, 0x53, 0x54,
            0x55, 0x67, 0x52, 0x53, 0x54, 0x55, 0x7E, 0x5C,
            0x00, 0x7E, 0x5F, 0x7B, 0x5C, 0x7E, 0x7E, 0x5F,
            0x76, 0x00, 0x67, 0x7E, 0x0C, 0x7E, 0x0E, 0x7E,
            0x7E, 0x7E, 0x12, 0x7E, 0x7E, 0x0C, 0x16, 0x0E,
            0x7E, 0x76, 0x7E, 0x12, 0x7E, 0x7E, 0x76, 0x16,
            0x7E, 0x21, 0x7E, 0x7E, 0x24, 0x25, 0x26, 0x00,
            0x7E, 0x7E, 0x21, 0x7E, 0x7E, 0x24, 0x25, 0x26,
            0x00, 0x7E, 0x7E, 0x0C, 0x7E, 0x0E, 0x7E, 0x7E,
            0x7E, 0x12, 0x7E, 0x7E, 0x0C, 0x16, 0x0E, 0x7E,
            0x7E, 0x7E, 0x12, 0x7E, 0x7E, 0x7E, 0x16, 0x7E,
            0x21, 0x7E, 0x7E, 0x24, 0x25, 0x26, 0x00, 0x7E,
            0x7E, 0x21, 0x7E, 0x7E, 0x24, 0x25, 0x26, 0x00,
            0x7E, 0x7E, 0x0C, 0x7E, 0x0E, 0x7E, 0x7E, 0x7E,
            0x12, 0x7E, 0x7E, 0x0C, 0x16, 0x0E, 0x7E, 0x7E,
            0x7E, 0x12, 0x7E, 0x7E, 0x7E, 0x16, 0x7E, 0x21,
            0x7E, 0x7E, 0x24, 0x25, 0x26, 0x00, 0x7E, 0x7E,
            0x21, 0x7E, 0x7E, 0x24, 0x25, 0x26, 0x7E, 0x7E,
            0x7E, 0x0C, 0x7E, 0x0E, 0x7E, 0x7E, 0x7E, 0x12,
            0x7E, 0x7E, 0x7E, 0x16, 0x01, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x07, 0x08, 0x09, 0x0A, 0x21, 0x7E,
            0x0D, 0x24, 0x25, 0x26, 0x00, 0x7E, 0x13, 0x14,
            0x15, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x0C, 0x0D, 0x0E, 0x7E, 0x10, 0x11, 0x23, 0x13,
            0x14, 0x00, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
            0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x0C, 0x0D, 0x0E,
            0x7E, 0x10, 0x11, 0x7E, 0x13, 0x14, 0x00, 0x16,
            0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
            0x1F, 0x20, 0x0C, 0x0D, 0x0E, 0x7E, 0x10, 0x11,
            0x7E, 0x13, 0x14, 0x00, 0x16, 0x17, 0x18, 0x19,
            0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x0C,
            0x0D, 0x0E, 0x7E, 0x10, 0x11, 0x7E, 0x13, 0x14,
            0x00, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C,
            0x1D, 0x1E, 0x1F, 0x20, 0x0C, 0x0D, 0x0E, 0x7E,
            0x10, 0x11, 0x7E, 0x13, 0x14, 0x00, 0x16, 0x17,
            0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
            0x20, 0x0C, 0x0D, 0x0E, 0x7E, 0x10, 0x11, 0x7E,
            0x13, 0x14, 0x00, 0x16, 0x17, 0x18, 0x19, 0x1A,
            0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x0C, 0x0D,
            0x0E, 0x7E, 0x10, 0x11, 0x7E, 0x13, 0x14, 0x00,
            0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
            0x1E, 0x1F, 0x20, 0x0C, 0x0D, 0x0E, 0x7E, 0x10,
            0x11, 0x7E, 0x13, 0x14, 0x00, 0x16, 0x17, 0x18,
            0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
            0x0C, 0x0D, 0x0E, 0x7E, 0x10, 0x11, 0x7E, 0x13,
            0x14, 0x00, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
            0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x0C, 0x0D, 0x0E,
            0x7E, 0x10, 0x11, 0x7E, 0x13, 0x14, 0x00, 0x16,
            0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
            0x1F, 0x20, 0x0C, 0x7E, 0x0E, 0x7E, 0x10, 0x7E,
            0x7E, 0x13, 0x14, 0x00, 0x16, 0x17, 0x18, 0x19,
            0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x0C,
            0x7E, 0x0E, 0x7E, 0x10, 0x7E, 0x7E, 0x13, 0x14,
            0x00, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C,
            0x1D, 0x1E, 0x1F, 0x20, 0x0C, 0x7E, 0x0E, 0x7E,
            0x10, 0x7E, 0x7E, 0x13, 0x14, 0x00, 0x16, 0x17,
            0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
            0x20, 0x0C, 0x7E, 0x0E, 0x7E, 0x10, 0x7E, 0x7E,
            0x13, 0x14, 0x00, 0x16, 0x17, 0x18, 0x19, 0x1A,
            0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x0C, 0x7E,
            0x0E, 0x7E, 0x10, 0x7E, 0x7E, 0x13, 0x14, 0x00,
            0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
            0x1E, 0x1F, 0x20, 0x0C, 0x7E, 0x0E, 0x7E, 0x10,
            0x7E, 0x7E, 0x13, 0x14, 0x00, 0x16, 0x17, 0x18,
            0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
            0x0C, 0x7E, 0x0E, 0x7E, 0x10, 0x7E, 0x7E, 0x13,
            0x14, 0x00, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
            0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x0C, 0x7E, 0x0E,
            0x7E, 0x10, 0x7E, 0x7E, 0x13, 0x14, 0x00, 0x16,
            0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
            0x1F, 0x20, 0x0C, 0x7E, 0x0E, 0x7E, 0x10, 0x7E,
            0x7E, 0x13, 0x14, 0x00, 0x16, 0x17, 0x18, 0x19,
            0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x0C,
            0x7E, 0x0E, 0x7E, 0x10, 0x7E, 0x7E, 0x13, 0x14,
            0x00, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C,
            0x1D, 0x1E, 0x1F, 0x20, 0x0C, 0x7E, 0x0E, 0x7E,
            0x10, 0x7E, 0x7E, 0x13, 0x14, 0x00, 0x7E, 0x7E,
            0x7E, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
            0x20, 0x0C, 0x7E, 0x0E, 0x7E, 0x10, 0x7E, 0x7E,
            0x13, 0x14, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x1D, 0x1E, 0x1F, 0x20, 0x0C, 0x7E,
            0x0E, 0x7E, 0x10, 0x7E, 0x7E, 0x13, 0x14, 0x00,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x1D,
            0x1E, 0x1F, 0x20, 0x0C, 0x7E, 0x0E, 0x7E, 0x10,
            0x7E, 0x7E, 0x13, 0x14, 0x00, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x1D, 0x1E, 0x1F, 0x20,
            0x0C, 0x7E, 0x0E, 0x7E, 0x10, 0x7E, 0x7E, 0x13,
            0x14, 0x00, 0x7E, 0x7E, 0x00, 0x7E, 0x7E, 0x00,
            0x7E, 0x1D, 0x1E, 0x1F, 0x20, 0x0C, 0x7E, 0x0E,
            0x0C, 0x10, 0x0E, 0x0C, 0x10, 0x0E, 0x7E, 0x10,
            0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x7E, 0x1D, 0x1E,
            0x1F, 0x20, 0x00, 0x1F, 0x20, 0x00, 0x1F, 0x20,
            0x0C, 0x7E, 0x0E, 0x7E, 0x10, 0x7E, 0x0C, 0x7E,
            0x0E, 0x0C, 0x10, 0x0E, 0x7E, 0x10, 0x7E, 0x7E,
            0x7E, 0x7E, 0x00, 0x1F, 0x20, 0x7E, 0x7E, 0x7E,
            0x7E, 0x1F, 0x20, 0x7E, 0x1F, 0x20, 0x0C, 0x7E,
            0x0E, 0x01, 0x10, 0x7E, 0x7E, 0x7E, 0x7E, 0x07,
            0x08, 0x09, 0x0A, 0x7E, 0x7E, 0x0D, 0x7E, 0x7E,
            0x7E, 0x1F, 0x20, 0x13, 0x14, 0x15, 0x02, 0x03,
            0x04, 0x05, 0x06, 0x7E, 0x7E, 0x09, 0x7E, 0x7E,
            0x7E, 0x0D, 0x02, 0x03, 0x04, 0x05, 0x7E, 0x7E,
            0x7E, 0x09, 0x7E, 0x7E, 0x7E, 0x0D, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
            0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E
        };

        private static readonly int[] _pvalue =
        {
            0x000A, 0x000A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03F2,
            0x0000, 0x0000, 0x0016, 0x000A, 0x000A, 0x000A, 0x0000, 0x0014,
            0x00E2, 0x0501, 0x0022, 0x000A, 0x0022, 0x0006, 0x00E2, 0x000A,
            0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A,
            0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x0009, 0x0009, 0x0043,
            0x03A2, 0x0561, 0x004B, 0x0049, 0x0561, 0x0044, 0x004A, 0x0671,
            0x0026, 0x0027, 0x0028, 0x03A2, 0x0551, 0x0611, 0x0591, 0x0761,
            0x0009, 0x0008, 0x0008, 0x00A2, 0x0009, 0x0009, 0x0009, 0x0009,
            0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0040, 0x0041,
            0x0042, 0x0009, 0x05F1, 0x00A2, 0x0008, 0x0601, 0x0006, 0x0006,
            0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
            0x003E, 0x003F, 0x000A, 0x0681, 0x05C1, 0x0008, 0x004E, 0x006D,
            0x0392, 0x0006, 0x00D2, 0x004E, 0x004F, 0x0006, 0x0006, 0x0038,
            0x0039, 0x004F, 0x000A, 0x0392, 0x000A, 0x0073, 0x0007, 0x0007,
            0x004B, 0x0075, 0x0006, 0x0044, 0x004A, 0x004D, 0x00F2, 0x00C2,
            0x00B2, 0x0047, 0x0057, 0x000A, 0x00F2, 0x00C2, 0x00B2, 0x0009,
            0x0291, 0x0007, 0x0005, 0x0005, 0x02A1, 0x0007, 0x0007, 0x0007,
            0x0007, 0x003A, 0x003B, 0x003C, 0x003D, 0x00C2, 0x00B2, 0x0009,
            0x06A1, 0x0009, 0x0007, 0x0008, 0x0042, 0x0005, 0x0042, 0x0004,
            0x0004, 0x0005, 0x0037, 0x0070, 0x0003, 0x0003, 0x05D1, 0x0072,
            0x0009, 0x0072, 0x0052, 0x0008, 0x0052, 0x0008, 0x0005, 0x03B2,
            0x0006, 0x0046, 0x0004, 0x0521, 0x0531, 0x0541, 0x0036, 0x0003,
            0x0002, 0x0016, 0x06C1, 0x03B2, 0x0008, 0x03B2, 0x0302, 0x0771,
            0x0006, 0x03B2, 0x0006, 0x0004, 0x0781, 0x05E1, 0x07B1, 0x0032,
            0x0003, 0x0092, 0x0302, 0x002B, 0x0302, 0x0791, 0x0302, 0x0092,
            0x0007, 0x0006, 0x04C1, 0x03B2, 0x03B2, 0x03B2, 0x0082, 0x002D,
            0x0082, 0x05A1, 0x0511, 0x0062, 0x0045, 0x0382, 0x0171, 0x0092,
            0x0007, 0x07D1, 0x0007, 0x03D2, 0x0005, 0x03C2, 0x06F1, 0x002D,
            0x002E, 0x0382, 0x03E2, 0x0382, 0x05B1, 0x002C, 0x0000, 0x0382,
            0x0000, 0x0007, 0x0000, 0x0000, 0x0005, 0x0000, 0x0005, 0x002D,
            0x002E, 0x0004, 0x0000, 0x0000, 0x0000, 0x0048, 0x0003, 0x0000,
            0x0000, 0x0382, 0x0382, 0x0382, 0x0000, 0x0005, 0x0000, 0x0000,
            0x002E, 0x0004, 0x0000, 0x0004, 0x0000, 0x0058, 0x0003, 0x0000,
            0x0003, 0x0000, 0x0069, 0x0000, 0x002D, 0x002D, 0x002D, 0x002D,
            0x0066, 0x0000, 0x0004, 0x0000, 0x0000, 0x0000, 0x002D, 0x0003,
            0x0000, 0x002D, 0x0045, 0x0000, 0x0074, 0x002E, 0x002E, 0x002E,
            0x002E, 0x0072, 0x0062, 0x0063, 0x0064, 0x0065, 0x0000, 0x002E,
            0x0372, 0x0000, 0x002E, 0x007C, 0x006B, 0x0000, 0x0000, 0x006E,
            0x002D, 0x0352, 0x0071, 0x0000, 0x0372, 0x0000, 0x0372, 0x0000,
            0x0000, 0x0000, 0x0372, 0x0000, 0x0000, 0x0352, 0x0392, 0x0352,
            0x0000, 0x002E, 0x0000, 0x0352, 0x0000, 0x0000, 0x007A, 0x0352,
            0x0000, 0x0392, 0x0000, 0x0000, 0x0372, 0x0372, 0x0372, 0x0342,
            0x0000, 0x0000, 0x0352, 0x0000, 0x0000, 0x0352, 0x0352, 0x0352,
            0x0332, 0x0000, 0x0000, 0x0342, 0x0000, 0x0342, 0x0000, 0x0000,
            0x0000, 0x0342, 0x0000, 0x0000, 0x0332, 0x0342, 0x0332, 0x0000,
            0x0000, 0x0000, 0x0332, 0x0000, 0x0000, 0x0000, 0x0332, 0x0000,
            0x0342, 0x0000, 0x0000, 0x0342, 0x0342, 0x0342, 0x0322, 0x0000,
            0x0000, 0x0332, 0x0000, 0x0000, 0x0332, 0x0332, 0x0332, 0x0312,
            0x0000, 0x0000, 0x0322, 0x0000, 0x0322, 0x0000, 0x0000, 0x0000,
            0x0322, 0x0000, 0x0000, 0x0312, 0x0322, 0x0312, 0x0000, 0x0000,
            0x0000, 0x0312, 0x0000, 0x0000, 0x0000, 0x0312, 0x0000, 0x0322,
            0x0000, 0x0000, 0x0322, 0x0322, 0x0322, 0x0362, 0x0000, 0x0000,
            0x0312, 0x0000, 0x0000, 0x0312, 0x0312, 0x0312, 0x0000, 0x0000,
            0x0000, 0x0362, 0x0000, 0x0362, 0x0000, 0x0000, 0x0000, 0x0362,
            0x0000, 0x0000, 0x0000, 0x0362, 0x0121, 0x0000, 0x0000, 0x0000,
            0x0000, 0x0000, 0x00F1, 0x0101, 0x00E1, 0x0111, 0x0362, 0x0000,
            0x0131, 0x0362, 0x0362, 0x0362, 0x0162, 0x0000, 0x00B1, 0x00C1,
            0x00D1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
            0x0162, 0x0162, 0x0162, 0x0000, 0x0162, 0x0162, 0x0151, 0x0162,
            0x0162, 0x0172, 0x0162, 0x0162, 0x0162, 0x0162, 0x0162, 0x0162,
            0x0162, 0x0162, 0x0162, 0x0162, 0x0162, 0x0172, 0x0172, 0x0172,
            0x0000, 0x0172, 0x0172, 0x0000, 0x0172, 0x0172, 0x0182, 0x0172,
            0x0172, 0x0172, 0x0172, 0x0172, 0x0172, 0x0172, 0x0172, 0x0172,
            0x0172, 0x0172, 0x0182, 0x0182, 0x0182, 0x0000, 0x0182, 0x0182,
            0x0000, 0x0182, 0x0182, 0x0142, 0x0182, 0x0182, 0x0182, 0x0182,
            0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0142,
            0x0142, 0x0142, 0x0000, 0x0142, 0x0142, 0x0000, 0x0142, 0x0142,
            0x0152, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142,
            0x0142, 0x0142, 0x0142, 0x0142, 0x0152, 0x0152, 0x0152, 0x0000,
            0x0152, 0x0152, 0x0000, 0x0152, 0x0152, 0x0132, 0x0152, 0x0152,
            0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152,
            0x0152, 0x0132, 0x0132, 0x0132, 0x0000, 0x0132, 0x0132, 0x0000,
            0x0132, 0x0132, 0x0122, 0x0132, 0x0132, 0x0132, 0x0132, 0x0132,
            0x0132, 0x0132, 0x0132, 0x0132, 0x0132, 0x0132, 0x0122, 0x0122,
            0x0122, 0x0000, 0x0122, 0x0122, 0x0000, 0x0122, 0x0122, 0x0192,
            0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
            0x0122, 0x0122, 0x0122, 0x0192, 0x0241, 0x0192, 0x0000, 0x0192,
            0x0251, 0x0000, 0x0192, 0x0192, 0x0102, 0x0192, 0x0192, 0x0192,
            0x0192, 0x0192, 0x0192, 0x0192, 0x0192, 0x0192, 0x0192, 0x0192,
            0x0102, 0x0102, 0x0102, 0x0000, 0x0102, 0x0102, 0x0000, 0x0102,
            0x0102, 0x0112, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
            0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0112, 0x0112, 0x0112,
            0x0000, 0x0112, 0x0112, 0x0000, 0x0112, 0x0112, 0x0212, 0x0112,
            0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112,
            0x0112, 0x0112, 0x0212, 0x0000, 0x0212, 0x0000, 0x0212, 0x0000,
            0x0000, 0x0212, 0x0212, 0x0222, 0x0211, 0x0221, 0x0231, 0x0212,
            0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0212, 0x0222,
            0x0000, 0x0222, 0x0000, 0x0222, 0x0000, 0x0000, 0x0222, 0x0222,
            0x0232, 0x0211, 0x0221, 0x0231, 0x0222, 0x0222, 0x0222, 0x0222,
            0x0222, 0x0222, 0x0222, 0x0222, 0x0232, 0x0000, 0x0232, 0x0000,
            0x0232, 0x0000, 0x0000, 0x0232, 0x0232, 0x01B2, 0x0211, 0x0221,
            0x0231, 0x0232, 0x0232, 0x0232, 0x0232, 0x0232, 0x0232, 0x0232,
            0x0232, 0x01B2, 0x0000, 0x01B2, 0x0000, 0x01B2, 0x0000, 0x0000,
            0x01B2, 0x01B2, 0x01A2, 0x01B2, 0x01B2, 0x01B2, 0x01B2, 0x01B2,
            0x01B2, 0x01B2, 0x01B2, 0x01B2, 0x01B2, 0x01B2, 0x01A2, 0x0000,
            0x01A2, 0x0000, 0x01A2, 0x0000, 0x0000, 0x01A2, 0x01A2, 0x01E2,
            0x01A2, 0x01A2, 0x01A2, 0x01A2, 0x01A2, 0x01A2, 0x01A2, 0x01A2,
            0x01A2, 0x01A2, 0x01A2, 0x01E2, 0x0000, 0x01E2, 0x0000, 0x01E2,
            0x0000, 0x0000, 0x01E2, 0x01E2, 0x01F2, 0x01E2, 0x01E2, 0x01E2,
            0x01E2, 0x01E2, 0x01E2, 0x01E2, 0x01E2, 0x01E2, 0x01E2, 0x01E2,
            0x01F2, 0x0000, 0x01F2, 0x0000, 0x01F2, 0x0000, 0x0000, 0x01F2,
            0x01F2, 0x0202, 0x01F2, 0x01F2, 0x01F2, 0x01F2, 0x01F2, 0x01F2,
            0x01F2, 0x01F2, 0x01F2, 0x01F2, 0x01F2, 0x0202, 0x0000, 0x0202,
            0x0000, 0x0202, 0x0000, 0x0000, 0x0202, 0x0202, 0x01C2, 0x0202,
            0x0202, 0x0202, 0x0202, 0x0202, 0x0202, 0x0202, 0x0202, 0x0202,
            0x0202, 0x0202, 0x01C2, 0x0000, 0x01C2, 0x0000, 0x01C2, 0x0000,
            0x0000, 0x01C2, 0x01C2, 0x01D2, 0x01C2, 0x01C2, 0x01C2, 0x01C2,
            0x01C2, 0x01C2, 0x01C2, 0x01C2, 0x01C2, 0x01C2, 0x01C2, 0x01D2,
            0x0000, 0x01D2, 0x0000, 0x01D2, 0x0000, 0x0000, 0x01D2, 0x01D2,
            0x0242, 0x01D2, 0x01D2, 0x01D2, 0x01D2, 0x01D2, 0x01D2, 0x01D2,
            0x01D2, 0x01D2, 0x01D2, 0x01D2, 0x0242, 0x0000, 0x0242, 0x0000,
            0x0242, 0x0000, 0x0000, 0x01F1, 0x0201, 0x0282, 0x0000, 0x0000,
            0x0000, 0x01B1, 0x01C1, 0x01D1, 0x01E1, 0x0242, 0x0242, 0x0242,
            0x0242, 0x0282, 0x0000, 0x0282, 0x0000, 0x0282, 0x0000, 0x0000,
            0x01F1, 0x0201, 0x0252, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
            0x0000, 0x0000, 0x0282, 0x0282, 0x0282, 0x0282, 0x0252, 0x0000,
            0x0252, 0x0000, 0x0252, 0x0000, 0x0000, 0x01F1, 0x0201, 0x0272,
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0252,
            0x0252, 0x0252, 0x0252, 0x0272, 0x0000, 0x0272, 0x0000, 0x0272,
            0x0000, 0x0000, 0x01F1, 0x0201, 0x0262, 0x0000, 0x0000, 0x0000,
            0x0000, 0x0000, 0x0000, 0x0000, 0x0272, 0x0272, 0x0272, 0x0272,
            0x0262, 0x0000, 0x0262, 0x0000, 0x0262, 0x0000, 0x0000, 0x01F1,
            0x0201, 0x0292, 0x0000, 0x0000, 0x02F2, 0x0000, 0x0000, 0x02D2,
            0x0000, 0x0262, 0x0262, 0x0262, 0x0262, 0x0292, 0x0000, 0x0292,
            0x02F2, 0x0292, 0x02F2, 0x02D2, 0x02F2, 0x02D2, 0x0000, 0x02D2,
            0x0000, 0x0000, 0x0000, 0x0000, 0x02A2, 0x0000, 0x0191, 0x01A1,
            0x0292, 0x0292, 0x02B2, 0x0181, 0x02F2, 0x02E2, 0x02D2, 0x02D2,
            0x02A2, 0x0000, 0x02A2, 0x0000, 0x02A2, 0x0000, 0x02B2, 0x0000,
            0x02B2, 0x02E2, 0x02B2, 0x02E2, 0x0000, 0x02E2, 0x0000, 0x0000,
            0x0000, 0x0000, 0x02C2, 0x02A2, 0x02A2, 0x0000, 0x0000, 0x0000,
            0x0000, 0x02B2, 0x02B2, 0x0000, 0x0181, 0x02E2, 0x02C2, 0x0000,
            0x02C2, 0x0121, 0x02C2, 0x0000, 0x0000, 0x0000, 0x0000, 0x00F1,
            0x0101, 0x00E1, 0x0111, 0x0000, 0x0000, 0x0131, 0x0000, 0x0000,
            0x0000, 0x02C2, 0x02C2, 0x00B1, 0x00C1, 0x00D1, 0x0311, 0x0321,
            0x0331, 0x0341, 0x02F1, 0x0000, 0x0000, 0x0301, 0x0000, 0x0000,
            0x0000, 0x0351, 0x0311, 0x0321, 0x0331, 0x0341, 0x0000, 0x0000,
            0x0000, 0x0301, 0x0000, 0x0000, 0x0000, 0x0351
        };

        private static int Map(int c)
        {
            if (0 <= c && c <= _fast.Length)
                return _fast[c];
            int i = 0;
            int j = _map.Length - 1;
            while (i <= j)
            {
                int k = i + (j - i >> 1);
                if (c < _first[k])
                    j = k - 1;
                else if (_last[k] < c)
                    i = k + 1;
                else
                    return _map[k];
            }
            return -1;
        }

        private static int Move(int state, int c)
        {
            int k = Map(c);
            if (k == -1)
                return -1;
            if (_scheck[_sbase[state] + k] == k)
                return _svalue[_sbase[state] + k];
            else
                return -1;
        }

        private static bool IsLineTerminator(int c)
        {
            switch (c)
            {
                case 0x000a: // '\n'
                case 0x000b: // '\v'
                case 0x000c: // '\f'
                case 0x000d: // '\r'
                case 0x0085: // '\u0085'
                case 0x2028: // '\u2028'
                case 0x2029: // '\u2029'
                    return true;
                default:
                    return false;
            }
        }

        private int ScanNextToken()
        {
            while (true)
            {
                TokenBegin = TokenEnd = Reader.Location;
                if (_start[_currentStart * 3 + 2] == 0 && Reader.Peek() == -1)
                    return 0;
                int saved = -1;
                int start = _currentStart;
                int state = _start[start * 3 + (Reader.Location.Offset == 0 ? 0 : 1)];
                while (true)
                {
                    int c = Reader.Read();
                    if (c == -1)
                        break;
                    int result = Move(state, c);
                    if (result == -1)
                        break;
                    int flag = _flag[result * 2];
                    if ((flag & 0x1) != 0)
                    {
                        int flag2 = _flag[result * 2 + 1];
                        bool atEOL = IsLineTerminator(Reader.Peek()) || Reader.Peek() == -1;
                        if ((flag & 0x2) == 0 || atEOL || (flag2 & 0x1) != 0)
                        {
                            TokenEnd = Reader.Location;
                            saved = result;
                        }
                    }
                    state = result;
                }
                if (saved == -1)
                {
                    Reader.Location = TokenBegin;
                    TokenContext = global::ParserGenerator.Input.SourceContext.New(TokenBegin, Reader.Location);
                    switch (start)
                    {
                        default:
                            throw SyntaxError(global::ParserGenerator.SR.InvalidToken);
                    }
                }
                else
                {
                    Reader.Location = TokenEnd;
                    TokenContext = global::ParserGenerator.Input.SourceContext.New(TokenBegin, Reader.Location);
                    int flag = _flag[saved * 2];
                    int flag2 = _flag[saved * 2 + 1];
                    bool atEOL = IsLineTerminator(Reader.Peek()) || Reader.Peek() == -1;
                    int action = (flag & 0x2) == 0 || atEOL ? flag : flag2;
                    if ((action & 0x4) != 0)
                        return action >> 4;
                    int rule = action >> 4;
                    switch (rule)
                    {
                        case 0:
                            // identifier
                            // #line 183 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"

                                ScanIdentifierName();
                                return 9;
                            // #line default
                        case 19:
                            // nl
                            // #line 180 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"

                                ;
                            // #line default
                            break;
                        case 20:
                            // ws
                            // #line 181 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"

                                ;
                            // #line default
                            break;
                        case 21:
                            // decimal_integer
                            // #line 184 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"

                                ScanIntegerValue();
                                return 10;
                            // #line default
                        default:
                            break;
                    }
                }
            }
        }

        public int GetNextToken()
        {
            TokenContext = null;
            TokenValue = null;
            int tag = ScanNextToken();
            if (TokenContext == null)
                TokenContext = global::ParserGenerator.Input.SourceContext.New(TokenBegin, Reader.Location);
            return tag;
        }

        public static int MapIdentifier(string name)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            switch (name)
            {
                case "def":
                    return 1;
                case "object":
                    return 2;
                case "null":
                    return 3;
                case "bool":
                    return 4;
                case "int":
                    return 5;
                case "forall":
                    return 6;
                case "false":
                    return 7;
                case "true":
                    return 8;
                default:
                    return 9;
            }
        }

        public static bool IsKeyword(string name)
        {
            if (name == null)
                throw new global::System.ArgumentNullException(nameof(name));
            switch (name)
            {
                case "def":
                case "object":
                case "null":
                case "bool":
                case "int":
                case "forall":
                case "false":
                case "true":
                    return true;
                default:
                    return false;
            }
        }

        private static int Action(int state, int c)
        {
            if (_pcheck[_pbase[state] + c] == c)
                return _pvalue[_pbase[state] + c];
            else
                return 0;
        }

        private static int Goto(int state, int c)
        {
            return _pvalue[_pbase[126 + c] + state];
        }

        private global::ParserGenerator.Exceptions.SyntaxErrorException MakeError(int state, int t)
        {
            global::System.Collections.Generic.List<string> tokens = new global::System.Collections.Generic.List<string>();
            for (int c = 0; c < _text.Length; c++)
            {
                int s = Action(state, c);
                if ((s & 0x1) != 0)
                    tokens.Add(_text[c]);
                else if ((s & 0x2) != 0)
                {
                    tokens.Clear();
                    break;
                }
            }
            string message;
            if (tokens.Count == 0)
                message = string.Format(global::ParserGenerator.SR.UnexpectedToken, _text[t]);
            else
            {
                global::System.Text.StringBuilder sb = new global::System.Text.StringBuilder();
                switch (tokens.Count)
                {
                    case 1:
                        sb.Append(tokens[0]);
                        break;
                    case 2:
                        sb.Append(tokens[0]);
                        sb.Append(" or ");
                        sb.Append(tokens[1]);
                        break;
                    case 3:
                        sb.Append(tokens[0]);
                        sb.Append(", ");
                        sb.Append(tokens[1]);
                        sb.Append(", or ");
                        sb.Append(tokens[2]);
                        break;
                    default:
                        sb.Append(tokens[0]);
                        sb.Append(", ");
                        sb.Append(tokens[1]);
                        sb.Append(", ..., or ");
                        sb.Append(tokens[tokens.Count - 1]);
                        break;
                }
                message = string.Format(global::ParserGenerator.SR.ExpectFound, sb.ToString(), _text[t]);
            }
            global::ParserGenerator.Exceptions.SyntaxErrorException e = new global::ParserGenerator.Exceptions.SyntaxErrorException(message);
            e.AddLocation(TokenContext);
            return e;
        }

        private object Reduce(int prod)
        {
            switch (prod)
            {
                case 0:
                    // Expression' -> Expression
                    return null;
                case 1:
                    // InteractiveTypeChecking' -> InteractiveTypeChecking
                    return null;
                case 2:
                    // Parameter -> Identifier ':' Type
                    {
                        Parameter result = default(Parameter);
                        // #line 90 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Parameter.New(((Identifier)(_values[_values.Count - 3])), ((Type)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 3:
                    // ParameterList -> Parameter %+ ','
                    {
                        ParameterList result = default(ParameterList);
                        // #line 92 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ParameterList.New(((global::ParserGenerator.Collections.Sequence<Parameter>)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 4:
                    // ParameterList' -> Parameter
                    {
                        global::ParserGenerator.Collections.Sequence<Parameter> result = default(global::ParserGenerator.Collections.Sequence<Parameter>);
                        result = Sequence.Create(((Parameter)(_values[_values.Count - 1])));
                        return result;
                    }
                case 5:
                    // ParameterList' -> ParameterList' ',' Parameter
                    {
                        global::ParserGenerator.Collections.Sequence<Parameter> result = default(global::ParserGenerator.Collections.Sequence<Parameter>);
                        result = Sequence.Append(((global::ParserGenerator.Collections.Sequence<Parameter>)(_values[_values.Count - 3])), ((Parameter)(_values[_values.Count - 1])));
                        return result;
                    }
                case 6:
                    // ArgumentList -> Expression %+ ','
                    {
                        ArgumentList result = default(ArgumentList);
                        // #line 94 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ArgumentList.New(((global::ParserGenerator.Collections.Sequence<Expression>)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 7:
                    // ExpressionList -> Expression
                    {
                        global::ParserGenerator.Collections.Sequence<Expression> result = default(global::ParserGenerator.Collections.Sequence<Expression>);
                        result = Sequence.Create(((Expression)(_values[_values.Count - 1])));
                        return result;
                    }
                case 8:
                    // ExpressionList -> ExpressionList ',' Expression
                    {
                        global::ParserGenerator.Collections.Sequence<Expression> result = default(global::ParserGenerator.Collections.Sequence<Expression>);
                        result = Sequence.Append(((global::ParserGenerator.Collections.Sequence<Expression>)(_values[_values.Count - 3])), ((Expression)(_values[_values.Count - 1])));
                        return result;
                    }
                case 9:
                    // TypeParameter -> Identifier
                    {
                        TypeParameter result = default(TypeParameter);
                        // #line 97 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = TypeParameter.New(((Identifier)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 10:
                    // TypeParameterList -> TypeParameter %+ ','
                    {
                        TypeParameterList result = default(TypeParameterList);
                        // #line 99 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = TypeParameterList.New(((global::ParserGenerator.Collections.Sequence<TypeParameter>)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 11:
                    // TypeParameterList' -> TypeParameter
                    {
                        global::ParserGenerator.Collections.Sequence<TypeParameter> result = default(global::ParserGenerator.Collections.Sequence<TypeParameter>);
                        result = Sequence.Create(((TypeParameter)(_values[_values.Count - 1])));
                        return result;
                    }
                case 12:
                    // TypeParameterList' -> TypeParameterList' ',' TypeParameter
                    {
                        global::ParserGenerator.Collections.Sequence<TypeParameter> result = default(global::ParserGenerator.Collections.Sequence<TypeParameter>);
                        result = Sequence.Append(((global::ParserGenerator.Collections.Sequence<TypeParameter>)(_values[_values.Count - 3])), ((TypeParameter)(_values[_values.Count - 1])));
                        return result;
                    }
                case 13:
                    // TypeArgumentList -> Type %+ ','
                    {
                        TypeArgumentList result = default(TypeArgumentList);
                        // #line 101 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = TypeArgumentList.New(((global::ParserGenerator.Collections.Sequence<Type>)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 14:
                    // TypeList -> Type
                    {
                        global::ParserGenerator.Collections.Sequence<Type> result = default(global::ParserGenerator.Collections.Sequence<Type>);
                        result = Sequence.Create(((Type)(_values[_values.Count - 1])));
                        return result;
                    }
                case 15:
                    // TypeList -> TypeList ',' Type
                    {
                        global::ParserGenerator.Collections.Sequence<Type> result = default(global::ParserGenerator.Collections.Sequence<Type>);
                        result = Sequence.Append(((global::ParserGenerator.Collections.Sequence<Type>)(_values[_values.Count - 3])), ((Type)(_values[_values.Count - 1])));
                        return result;
                    }
                case 16:
                    // PrimaryExpression -> Identifier
                    {
                        Expression result = default(Expression);
                        // #line 104 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewVariable(((Identifier)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 17:
                    // PrimaryExpression -> 'false'
                    {
                        Expression result = default(Expression);
                        // #line 105 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewFalse(_nodeContext);
                        // #line default
                        return result;
                    }
                case 18:
                    // PrimaryExpression -> 'true'
                    {
                        Expression result = default(Expression);
                        // #line 106 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewTrue(_nodeContext);
                        // #line default
                        return result;
                    }
                case 19:
                    // PrimaryExpression -> IntLiteral
                    {
                        Expression result = default(Expression);
                        // #line 107 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewIntLiteral(((IntLiteral)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 20:
                    // PrimaryExpression -> 'def' '(' ParameterList ')' '{' Expression '}'
                    {
                        Expression result = default(Expression);
                        // #line 108 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewFunction(null, ((ParameterList)(_values[_values.Count - 5])), ((Expression)(_values[_values.Count - 2])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 21:
                    // PrimaryExpression -> 'def' '[' TypeParameterList ']' '(' ParameterList ')' '{' Expression '}'
                    {
                        Expression result = default(Expression);
                        // #line 109 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewFunction(((TypeParameterList)(_values[_values.Count - 8])), ((ParameterList)(_values[_values.Count - 5])), ((Expression)(_values[_values.Count - 2])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 22:
                    // PrimaryExpression -> '(' Expression ')'
                    {
                        Expression result = default(Expression);
                        // #line 110 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewGroup(((Expression)(_values[_values.Count - 2])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 23:
                    // PrimaryExpression -> PrimaryExpression '(' ArgumentList ')'
                    {
                        Expression result = default(Expression);
                        // #line 111 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewCall(((Expression)(_values[_values.Count - 4])), null, ((ArgumentList)(_values[_values.Count - 2])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 24:
                    // PrimaryExpression -> PrimaryExpression '[' TypeArgumentList ']' '(' ArgumentList ')'
                    {
                        Expression result = default(Expression);
                        // #line 112 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewCall(((Expression)(_values[_values.Count - 7])), ((TypeArgumentList)(_values[_values.Count - 5])), ((ArgumentList)(_values[_values.Count - 2])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 25:
                    // UnaryExpression -> PrimaryExpression
                    {
                        Expression result = default(Expression);
                        // #line 114 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ((Expression)(_values[_values.Count - 1]));
                        // #line default
                        return result;
                    }
                case 26:
                    // UnaryExpression -> '+' UnaryExpression
                    {
                        Expression result = default(Expression);
                        // #line 115 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewUnary(UnaryOp.NewPositive(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 27:
                    // UnaryExpression -> '-' UnaryExpression
                    {
                        Expression result = default(Expression);
                        // #line 116 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewUnary(UnaryOp.NewNegative(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 28:
                    // UnaryExpression -> '!' UnaryExpression
                    {
                        Expression result = default(Expression);
                        // #line 117 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewUnary(UnaryOp.NewLogicalNot(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 29:
                    // MultiplicativeExpression -> UnaryExpression
                    {
                        Expression result = default(Expression);
                        // #line 119 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ((Expression)(_values[_values.Count - 1]));
                        // #line default
                        return result;
                    }
                case 30:
                    // MultiplicativeExpression -> MultiplicativeExpression '*' UnaryExpression
                    {
                        Expression result = default(Expression);
                        // #line 120 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewMultiply(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 31:
                    // MultiplicativeExpression -> MultiplicativeExpression '/' UnaryExpression
                    {
                        Expression result = default(Expression);
                        // #line 121 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewDivide(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 32:
                    // MultiplicativeExpression -> MultiplicativeExpression '%' UnaryExpression
                    {
                        Expression result = default(Expression);
                        // #line 122 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewModulo(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 33:
                    // AdditiveExpression -> MultiplicativeExpression
                    {
                        Expression result = default(Expression);
                        // #line 124 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ((Expression)(_values[_values.Count - 1]));
                        // #line default
                        return result;
                    }
                case 34:
                    // AdditiveExpression -> AdditiveExpression '+' MultiplicativeExpression
                    {
                        Expression result = default(Expression);
                        // #line 125 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewAdd(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 35:
                    // AdditiveExpression -> AdditiveExpression '-' MultiplicativeExpression
                    {
                        Expression result = default(Expression);
                        // #line 126 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewSubtract(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 36:
                    // RelationalExpression -> AdditiveExpression
                    {
                        Expression result = default(Expression);
                        // #line 128 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ((Expression)(_values[_values.Count - 1]));
                        // #line default
                        return result;
                    }
                case 37:
                    // RelationalExpression -> AdditiveExpression '<' AdditiveExpression
                    {
                        Expression result = default(Expression);
                        // #line 129 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewLessThan(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 38:
                    // RelationalExpression -> AdditiveExpression '<=' AdditiveExpression
                    {
                        Expression result = default(Expression);
                        // #line 130 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewLessEqual(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 39:
                    // RelationalExpression -> AdditiveExpression '>' AdditiveExpression
                    {
                        Expression result = default(Expression);
                        // #line 131 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewGreaterThan(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 40:
                    // RelationalExpression -> AdditiveExpression '>=' AdditiveExpression
                    {
                        Expression result = default(Expression);
                        // #line 132 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewGreaterEqual(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 41:
                    // EqualityExpression -> RelationalExpression
                    {
                        Expression result = default(Expression);
                        // #line 134 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ((Expression)(_values[_values.Count - 1]));
                        // #line default
                        return result;
                    }
                case 42:
                    // EqualityExpression -> RelationalExpression '==' RelationalExpression
                    {
                        Expression result = default(Expression);
                        // #line 135 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewEqualTo(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 43:
                    // EqualityExpression -> RelationalExpression '!=' RelationalExpression
                    {
                        Expression result = default(Expression);
                        // #line 136 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewNotEqualTo(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 44:
                    // LogicalAndExpression -> EqualityExpression
                    {
                        Expression result = default(Expression);
                        // #line 138 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ((Expression)(_values[_values.Count - 1]));
                        // #line default
                        return result;
                    }
                case 45:
                    // LogicalAndExpression -> LogicalAndExpression '&&' EqualityExpression
                    {
                        Expression result = default(Expression);
                        // #line 139 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewLogicalAnd(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 46:
                    // LogicalOrExpression -> LogicalAndExpression
                    {
                        Expression result = default(Expression);
                        // #line 141 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ((Expression)(_values[_values.Count - 1]));
                        // #line default
                        return result;
                    }
                case 47:
                    // LogicalOrExpression -> LogicalOrExpression '||' LogicalAndExpression
                    {
                        Expression result = default(Expression);
                        // #line 142 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Expression.NewBinary(((Expression)(_values[_values.Count - 3])), BinaryOp.NewLogicalOr(_contexts[_contexts.Count - 2]), ((Expression)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 48:
                    // Expression -> LogicalOrExpression
                    {
                        Expression result = default(Expression);
                        // #line 144 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ((Expression)(_values[_values.Count - 1]));
                        // #line default
                        return result;
                    }
                case 49:
                    // PrimaryType -> Identifier
                    {
                        Type result = default(Type);
                        // #line 147 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Type.NewVariable(((Identifier)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 50:
                    // PrimaryType -> 'object'
                    {
                        Type result = default(Type);
                        // #line 148 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Type.NewObject(_nodeContext);
                        // #line default
                        return result;
                    }
                case 51:
                    // PrimaryType -> 'null'
                    {
                        Type result = default(Type);
                        // #line 149 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Type.NewNull(_nodeContext);
                        // #line default
                        return result;
                    }
                case 52:
                    // PrimaryType -> 'bool'
                    {
                        Type result = default(Type);
                        // #line 150 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Type.NewBool(_nodeContext);
                        // #line default
                        return result;
                    }
                case 53:
                    // PrimaryType -> 'int'
                    {
                        Type result = default(Type);
                        // #line 151 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Type.NewInt(_nodeContext);
                        // #line default
                        return result;
                    }
                case 54:
                    // PrimaryType -> '(' Type ')'
                    {
                        Type result = default(Type);
                        // #line 152 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ((Type)(_values[_values.Count - 2]));
                        // #line default
                        return result;
                    }
                case 55:
                    // Type -> PrimaryType
                    {
                        Type result = default(Type);
                        // #line 154 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = ((Type)(_values[_values.Count - 1]));
                        // #line default
                        return result;
                    }
                case 56:
                    // Type -> PrimaryType %+ '*' '->' Type
                    {
                        Type result = default(Type);
                        // #line 155 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Type.NewFunction(null, ((global::ParserGenerator.Collections.Sequence<Type>)(_values[_values.Count - 3])), ((Type)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 57:
                    // PrimaryTypeList -> PrimaryType
                    {
                        global::ParserGenerator.Collections.Sequence<Type> result = default(global::ParserGenerator.Collections.Sequence<Type>);
                        result = Sequence.Create(((Type)(_values[_values.Count - 1])));
                        return result;
                    }
                case 58:
                    // PrimaryTypeList -> PrimaryTypeList '*' PrimaryType
                    {
                        global::ParserGenerator.Collections.Sequence<Type> result = default(global::ParserGenerator.Collections.Sequence<Type>);
                        result = Sequence.Append(((global::ParserGenerator.Collections.Sequence<Type>)(_values[_values.Count - 3])), ((Type)(_values[_values.Count - 1])));
                        return result;
                    }
                case 59:
                    // Type -> 'forall' TypeParameterList '.' PrimaryType %+ '*' '->' Type
                    {
                        Type result = default(Type);
                        // #line 156 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"
                        result = Type.NewFunction(((TypeParameterList)(_values[_values.Count - 5])), ((global::ParserGenerator.Collections.Sequence<Type>)(_values[_values.Count - 3])), ((Type)(_values[_values.Count - 1])), _nodeContext);
                        // #line default
                        return result;
                    }
                case 60:
                    // InteractiveTypeChecking -> '?' Type '<:' Type
                    {
                        // #line 159 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"

                            System.Console.WriteLine(((LocalTypeInferenceTypeChecker.IsSubtypeOf(((Type)(_values[_values.Count - 3])), ((Type)(_values[_values.Count - 1])))) ? ("yes") : ("no")));
                        // #line default
                        return null;
                    }
                case 61:
                    // InteractiveTypeChecking -> '?' Type '\\/' Type
                    {
                        // #line 160 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"

                            System.Console.WriteLine(LocalTypeInferenceTypeChecker.JoinType(((Type)(_values[_values.Count - 3])), ((Type)(_values[_values.Count - 1]))));
                        // #line default
                        return null;
                    }
                case 62:
                    // InteractiveTypeChecking -> '?' Type '/\\' Type
                    {
                        // #line 161 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"

                            System.Console.WriteLine(LocalTypeInferenceTypeChecker.MeetType(((Type)(_values[_values.Count - 3])), ((Type)(_values[_values.Count - 1]))));
                        // #line default
                        return null;
                    }
                case 63:
                    // InteractiveTypeChecking -> Expression
                    {
                        // #line 162 "C:\Users\huaidong.xiong\Documents\git\ParserGenerator\ParserGenerator\ParserGenerator.Languages\LocalTypeInference\LocalTypeInference.g"

                            System.Console.WriteLine(LocalTypeInferenceTypeChecker.TypeCheck(((Expression)(_values[_values.Count - 1]))));
                        // #line default
                        return null;
                    }
                default:
                    return null;
            }
        }

        private object ParseGoal(int goal)
        {
            int state = _goal[goal];
            _states.Add(state);
            int t = GetNextToken();
            while (true)
            {
                int s = Action(state, t);
                if ((s & 0x1) != 0)
                {
                    state = s >> 4;
                    _states.Add(state);
                    _symbols.Add(_tokens[t]);
                    _values.Add(TokenValue);
                    _contexts.Add(TokenContext);
                    t = GetNextToken();
                }
                else if ((s & 0x2) != 0)
                {
                    int prod = s >> 4;
                    int left = _left[prod];
                    int length = _length[prod];
                    if (length == 0)
                        _nodeContext = global::ParserGenerator.Input.SourceContext.New(TokenContext.Begin, TokenContext.Begin);
                    else
                        _nodeContext = global::ParserGenerator.Input.SourceContext.New(_contexts[_contexts.Count - length].Begin, _contexts[_contexts.Count - 1].End);
                    if ((s & 0x4) != 0)
                    {
                        object result = _values[0];
                        _states.Clear();
                        _symbols.Clear();
                        _values.Clear();
                        _contexts.Clear();
                        return result;
                    }
                    else
                    {
                        object value = Reduce(prod);
                        if (length > 0)
                        {
                            _states.RemoveRange(_states.Count - length, length);
                            _symbols.RemoveRange(_symbols.Count - length, length);
                            _values.RemoveRange(_values.Count - length, length);
                            _contexts.RemoveRange(_contexts.Count - length, length);
                        }
                        state = Goto(_states[_states.Count - 1], left);
                        _states.Add(state);
                        _symbols.Add(_nonterminals[left]);
                        _values.Add(value);
                        _contexts.Add(_nodeContext);
                    }
                }
                else
                {
                    throw MakeError(state, t);
                }
            }
        }

        public void Parse()
        {
            ParseInteractiveTypeChecking();
        }

        public Expression ParseExpression()
        {
            return (Expression)ParseGoal(0);
        }

        public void ParseInteractiveTypeChecking()
        {
            ParseGoal(1);
        }

        public static void TestTokenizer()
        {
            while (true)
            {
                global::ParserGenerator.Input.SourceReader reader = global::ParserGenerator.Input.SourceReader.FromConsole();
                if (reader.Peek() == -1)
                    break;
                try
                {
                    global::ParserGenerator.Languages.LocalTypeInference.LocalTypeInferenceProgramParser tokenizer = new global::ParserGenerator.Languages.LocalTypeInference.LocalTypeInferenceProgramParser(reader);
                    while (true)
                    {
                        int tag = tokenizer.GetNextToken();
                        global::System.Console.WriteLine("{0}: {1} {2}", tokenizer.TokenContext.Begin, _tokens[tag], tokenizer.TokenContext);
                        if (tag == 0)
                            break;
                    }
                }
                catch (global::System.Exception e)
                {
                    global::ParserGenerator.Extensions.ExceptionExtensions.Print(e);
                }
            }
        }

        public static void Test()
        {
            while (true)
            {
                global::ParserGenerator.Input.SourceReader reader = global::ParserGenerator.Input.SourceReader.FromConsole();
                if (reader.Peek() == -1)
                    break;
                try
                {
                    global::ParserGenerator.Languages.LocalTypeInference.LocalTypeInferenceProgramParser parser = new global::ParserGenerator.Languages.LocalTypeInference.LocalTypeInferenceProgramParser(reader);
                    parser.Parse();
                }
                catch (global::System.Exception e)
                {
                    global::ParserGenerator.Extensions.ExceptionExtensions.Print(e);
                }
            }
        }
    }
}
